home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH4 / SRC / AVERAGE.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-01-03  |  14.3 KB  |  455 lines

  1. VERSION 4.00
  2. Begin VB.Form AverageForm 
  3.    BorderStyle     =   1  'Fixed Single
  4.    Caption         =   "Average"
  5.    ClientHeight    =   5700
  6.    ClientLeft      =   1875
  7.    ClientTop       =   825
  8.    ClientWidth     =   5925
  9.    Height          =   6390
  10.    Left            =   1815
  11.    LinkTopic       =   "Form1"
  12.    MaxButton       =   0   'False
  13.    MinButton       =   0   'False
  14.    ScaleHeight     =   380
  15.    ScaleMode       =   3  'Pixel
  16.    ScaleWidth      =   395
  17.    Top             =   195
  18.    Width           =   6045
  19.    Begin VB.PictureBox Pict 
  20.       AutoRedraw      =   -1  'True
  21.       Height          =   2775
  22.       Index           =   3
  23.       Left            =   3000
  24.       Picture         =   "AVERAGE.frx":0000
  25.       ScaleHeight     =   2715
  26.       ScaleWidth      =   2835
  27.       TabIndex        =   3
  28.       Top             =   2880
  29.       Width           =   2895
  30.    End
  31.    Begin VB.PictureBox Pict 
  32.       AutoRedraw      =   -1  'True
  33.       Height          =   2775
  34.       Index           =   2
  35.       Left            =   0
  36.       Picture         =   "AVERAGE.frx":0446
  37.       ScaleHeight     =   2715
  38.       ScaleWidth      =   2835
  39.       TabIndex        =   2
  40.       Top             =   2880
  41.       Width           =   2895
  42.    End
  43.    Begin VB.PictureBox Pict 
  44.       AutoRedraw      =   -1  'True
  45.       Height          =   2775
  46.       Index           =   1
  47.       Left            =   3000
  48.       ScaleHeight     =   2715
  49.       ScaleWidth      =   2835
  50.       TabIndex        =   1
  51.       Top             =   0
  52.       Width           =   2895
  53.    End
  54.    Begin VB.PictureBox Pict 
  55.       AutoRedraw      =   -1  'True
  56.       Height          =   2775
  57.       Index           =   0
  58.       Left            =   0
  59.       ScaleHeight     =   2715
  60.       ScaleWidth      =   2835
  61.       TabIndex        =   0
  62.       Top             =   0
  63.       Width           =   2895
  64.    End
  65.    Begin MSComDlg.CommonDialog FileDialog 
  66.       Left            =   2760
  67.       Top             =   360
  68.       _Version        =   65536
  69.       _ExtentX        =   847
  70.       _ExtentY        =   847
  71.       _StockProps     =   0
  72.       CancelError     =   -1  'True
  73.    End
  74.    Begin VB.Menu mnuFile 
  75.       Caption         =   "&File"
  76.       Begin VB.Menu mnuFileLoad 
  77.          Caption         =   "Load Image &1..."
  78.          Index           =   0
  79.       End
  80.       Begin VB.Menu mnuFileLoad 
  81.          Caption         =   "Load Image &2..."
  82.          Index           =   1
  83.       End
  84.       Begin VB.Menu mnuFileLoad 
  85.          Caption         =   "Load Image &3..."
  86.          Index           =   2
  87.       End
  88.       Begin VB.Menu mnuFileSep2 
  89.          Caption         =   "-"
  90.       End
  91.       Begin VB.Menu mnuFileExit 
  92.          Caption         =   "E&xit"
  93.       End
  94.    End
  95.    Begin VB.Menu mnuOp 
  96.       Caption         =   "&Operation"
  97.       Begin VB.Menu mnuOpAverage 
  98.          Caption         =   "&Average"
  99.          Enabled         =   0   'False
  100.       End
  101.       Begin VB.Menu mnuOpVote 
  102.          Caption         =   "&Vote"
  103.          Enabled         =   0   'False
  104.       End
  105.    End
  106. Attribute VB_Name = "AverageForm"
  107. Attribute VB_Creatable = False
  108. Attribute VB_Exposed = False
  109. Option Explicit
  110. Dim SysPalSize As Integer
  111. Dim NumStaticColors As Integer
  112. Dim StaticColor1 As Integer
  113. Dim StaticColor2 As Integer
  114. Dim bytes0() As Byte
  115. Dim bytes1() As Byte
  116. Dim bytes2() As Byte
  117. Dim bytes3() As Byte
  118. Dim wid(0 To 3) As Long
  119. Dim hgt(0 To 3) As Long
  120. Dim PictLoaded(0 To 2) As Boolean
  121. Dim dgray As Single
  122. ' ************************************************
  123. ' Return the value of the indicated non-static
  124. ' palette entry (assuming the non-static colors
  125. ' are a gray scale created by MatchGrayPalette).
  126. ' ************************************************
  127. Function NonstaticGrayValue(ByVal Index As Integer) As Integer
  128.     NonstaticGrayValue = (Index - StaticColor1 - 1) * dgray
  129. End Function
  130. ' ************************************************
  131. ' Return the index of the nonstatic gray closest
  132. ' to the given value (assuming the non-static
  133. ' colors are a gray scale created by
  134. ' MatchGrayPalette).
  135. ' ************************************************
  136. Function NearestNonstaticGray(c As Integer) As Integer
  137. Dim dgray As Single
  138.     If c < 0 Then
  139.         c = 0
  140.     ElseIf c > 255 Then
  141.         c = 255
  142.     End If
  143.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  144.     NearestNonstaticGray = c / dgray + StaticColor1 + 1
  145. End Function
  146. ' ***********************************************
  147. ' Load the indicated file and prepare to work
  148. ' with its palette.
  149. ' ***********************************************
  150. Sub LoadPict(Index As Integer, fname As String)
  151. Dim i As Integer
  152.     On Error GoTo LoadFileError
  153.     Pict(Index).Picture = LoadPicture(fname)
  154.     On Error GoTo 0
  155.     Select Case Index
  156.         Case 0
  157.             MatchGrayPalette Index, Pict(Index), bytes0
  158.         Case 1
  159.             MatchGrayPalette Index, Pict(Index), bytes1
  160.         Case 2
  161.             MatchGrayPalette Index, Pict(Index), bytes2
  162.     End Select
  163.     PictLoaded(Index) = True
  164.     If PictLoaded(0) And PictLoaded(1) And _
  165.         PictLoaded(1) Then
  166.             mnuOpAverage.Enabled = True
  167.             mnuOpVote.Enabled = True
  168.     End If
  169.     Exit Sub
  170. LoadFileError:
  171.     Beep
  172.     MsgBox "Error loading file " & fname & "." & _
  173.         vbCrLf & Error$
  174.     Exit Sub
  175. End Sub
  176. Private Sub Form_Unload(Cancel As Integer)
  177.     End
  178. End Sub
  179. ' ************************************************
  180. ' Compute a voting average for the input images.
  181. ' ************************************************
  182. Private Sub mnuOpVote_Click()
  183. Dim x As Integer
  184. Dim y As Integer
  185. Dim maxx As Long
  186. Dim maxy As Long
  187. Dim c0 As Integer
  188. Dim c1 As Integer
  189. Dim c2 As Integer
  190. Dim status As Long
  191.     WaitStart
  192.     ' Get bounds for the new image.
  193.     maxx = wid(0)
  194.     If maxx > wid(1) Then maxx = wid(1)
  195.     If maxx > wid(2) Then maxx = wid(2)
  196.     maxy = hgt(0)
  197.     If maxy > hgt(1) Then maxy = hgt(1)
  198.     If maxy > hgt(2) Then maxy = hgt(2)
  199.     ' Size the result array.
  200.     ReDim bytes3(1 To maxx, 1 To maxy)
  201.     ' Create the result.
  202.     For y = 1 To maxy
  203.         For x = 1 To maxx
  204.             c0 = NonstaticGrayValue(bytes0(x, y))
  205.             c1 = NonstaticGrayValue(bytes1(x, y))
  206.             c2 = NonstaticGrayValue(bytes2(x, y))
  207.             If c0 = c1 Then
  208.                 bytes3(x, y) = _
  209.                     NearestNonstaticGray(c0)
  210.             ElseIf c1 = c2 Then
  211.                 bytes3(x, y) = _
  212.                     NearestNonstaticGray(c1)
  213.             ElseIf c2 = c1 Then
  214.                 bytes3(x, y) = _
  215.                     NearestNonstaticGray(c2)
  216.             Else
  217.                 bytes3(x, y) = _
  218.                     NearestNonstaticGray((c0 + c1 + c2) / 3)
  219.             End If
  220.         Next x
  221.     Next y
  222.     ' Display the result.
  223.     status = SetBitmapBits(Pict(3).Image, CLng(maxx) * maxy, bytes3(1, 1))
  224.     Pict(3).Refresh
  225.     WaitEnd
  226. End Sub
  227. ' ************************************************
  228. ' Average the three input images.
  229. ' ************************************************
  230. Private Sub mnuOpAverage_Click()
  231. Dim x As Integer
  232. Dim y As Integer
  233. Dim maxx As Long
  234. Dim maxy As Long
  235. Dim c0 As Integer
  236. Dim c1 As Integer
  237. Dim c2 As Integer
  238. Dim status As Long
  239.     WaitStart
  240.     ' Get bounds for the new image.
  241.     maxx = wid(0)
  242.     If maxx > wid(1) Then maxx = wid(1)
  243.     If maxx > wid(2) Then maxx = wid(2)
  244.     maxy = hgt(0)
  245.     If maxy > hgt(1) Then maxy = hgt(1)
  246.     If maxy > hgt(2) Then maxy = hgt(2)
  247.     ' Size the result array.
  248.     ReDim bytes3(1 To maxx, 1 To maxy)
  249.     ' Create the result.
  250.     For y = 1 To maxy
  251.         For x = 1 To maxx
  252.             c0 = NonstaticGrayValue(bytes0(x, y))
  253.             c1 = NonstaticGrayValue(bytes1(x, y))
  254.             c2 = NonstaticGrayValue(bytes2(x, y))
  255.             bytes3(x, y) = _
  256.                 NearestNonstaticGray((c0 + c1 + c2) / 3)
  257.         Next x
  258.     Next y
  259.     ' Display the result.
  260.     status = SetBitmapBits(Pict(3).Image, CLng(maxx) * maxy, bytes3(1, 1))
  261.     Pict(3).Refresh
  262.     WaitEnd
  263. End Sub
  264. ' ***********************************************
  265. ' Load the control's palette so the non-static
  266. ' colors are grays. Map the logical palette to
  267. ' match the system palette. Convert the image to
  268. ' use the non-static grays.
  269. ' Set the following parameters.
  270. '   wid(Index)  Width of image.
  271. '   hgt(Index)  Height of image.
  272. '   bytes(1 To wid, 1 To hgt)
  273. '               Image pixel values.
  274. ' ***********************************************
  275. Sub MatchGrayPalette(Index As Integer, pic As Control, bytes() As Byte)
  276. Dim hPal As Integer
  277. Dim sysentry(0 To 255) As PALETTEENTRY
  278. Dim logentry(0 To 255) As PALETTEENTRY
  279. Dim i As Integer
  280. Dim bm As BITMAP
  281. Dim hbm As Integer
  282. Dim status As Long
  283. Dim x As Integer
  284. Dim y As Integer
  285. Dim gray As Single
  286. Dim dgray As Single
  287. Dim c As Integer
  288. Dim clr As Integer
  289.     ' Make sure pic has the foreground palette.
  290.     pic.ZOrder
  291.     i = RealizePalette(pic.hdc)
  292.     DoEvents
  293.     ' Get the system palette entries.
  294.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sysentry(0))
  295.         
  296.     ' Get the image pixels.
  297.     hbm = pic.Image
  298.     status = GetObject(hbm, BITMAP_SIZE, bm)
  299.     wid(Index) = bm.bmWidthBytes
  300.     hgt(Index) = bm.bmHeight
  301.     ReDim bytes(1 To wid(Index), 1 To hgt(Index))
  302.     status = GetBitmapBits(hbm, wid(Index) * hgt(Index), bytes(1, 1))
  303.     ' Make the logical palette as big as possible.
  304.     hPal = pic.Picture.hPal
  305.     If ResizePalette(hPal, SysPalSize) = 0 Then
  306.         Beep
  307.         MsgBox "Error resizing logical palette.", _
  308.             vbExclamation
  309.         Exit Sub
  310.     End If
  311.     ' Blank the non-static colors.
  312.     For i = 0 To StaticColor1
  313.         logentry(i) = sysentry(i)
  314.     Next i
  315.     For i = StaticColor1 + 1 To StaticColor2 - 1
  316.         With logentry(i)
  317.             .peRed = 0
  318.             .peGreen = 0
  319.             .peBlue = 0
  320.             .peFlags = PC_NOCOLLAPSE
  321.         End With
  322.     Next i
  323.     For i = StaticColor2 To 255
  324.         logentry(i) = sysentry(i)
  325.     Next i
  326.     i = SetPaletteEntries(hPal, 0, SysPalSize, logentry(0))
  327.     ' Insert the non-static grays.
  328.     gray = 0
  329.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  330.     For i = StaticColor1 + 1 To StaticColor2 - 1
  331.         c = gray
  332.         gray = gray + dgray
  333.         With logentry(i)
  334.             .peRed = c
  335.             .peGreen = c
  336.             .peBlue = c
  337.         End With
  338.     Next i
  339.     i = SetPaletteEntries(hPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, logentry(StaticColor1 + 1))
  340.     ' Recreate the image using the new colors.
  341.     For y = 1 To hgt(Index)
  342.         For x = 1 To wid(Index)
  343.             clr = bytes(x, y)
  344.             With sysentry(clr)
  345.                 c = (CInt(.peRed) + .peGreen + .peBlue) / 3
  346.             End With
  347.             bytes(x, y) = NearestNonstaticGray(c)
  348.         Next x
  349.     Next y
  350.     status = SetBitmapBits(hbm, wid(Index) * hgt(Index), bytes(1, 1))
  351.     ' Realize the gray palette.
  352.     i = RealizePalette(pic.hdc)
  353.     pic.Refresh
  354. End Sub
  355. ' ***********************************************
  356. ' Give the form and all the picture boxes an
  357. ' hourglass cursor.
  358. ' ***********************************************
  359. Sub WaitStart()
  360. Dim i As Integer
  361.     MousePointer = vbHourglass
  362.     For i = 0 To 2
  363.         Pict(i).MousePointer = vbHourglass
  364.     Next i
  365.     DoEvents
  366. End Sub
  367. ' ***********************************************
  368. ' Restore the mouse pointers for the form and all
  369. ' the picture boxes.
  370. ' ***********************************************
  371. Sub WaitEnd()
  372. Dim i As Integer
  373.     MousePointer = vbDefault
  374.     For i = 0 To 2
  375.         Pict(i).MousePointer = vbDefault
  376.     Next i
  377. End Sub
  378. Private Sub Form_Load()
  379.     ' Make sure the screen supports palettes.
  380.     If Not GetDeviceCaps(hdc, RASTERCAPS) And RC_PALETTE Then
  381.         Beep
  382.         MsgBox "This monitor does not support palettes.", _
  383.             vbCritical
  384.         End
  385.     End If
  386.     ' Get system palette size and # static colors.
  387.     SysPalSize = GetDeviceCaps(hdc, SIZEPALETTE)
  388.     NumStaticColors = GetDeviceCaps(hdc, NUMRESERVED)
  389.     StaticColor1 = NumStaticColors \ 2 - 1
  390.     StaticColor2 = SysPalSize - NumStaticColors \ 2
  391.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  392.     ' Fill the result picture's palette with grays.
  393.     MatchGrayPalette 3, Pict(3), bytes3
  394. End Sub
  395. ' ***********************************************
  396. ' Make the picture as large as possible.
  397. ' ***********************************************
  398. Private Sub Form_Resize()
  399. Const GAP = 2
  400. Dim wid As Single
  401. Dim hgt As Single
  402.     If WindowState = vbMinimized Then Exit Sub
  403.         
  404.     wid = (ScaleWidth - GAP - 1) / 2
  405.     hgt = (ScaleHeight - GAP - 1) / 2
  406.     Pict(0).Move 0, 0, wid, hgt
  407.     Pict(1).Move Pict(0).Left + Pict(0).Width + GAP, _
  408.         0, wid, hgt
  409.     Pict(2).Move 0, Pict(1).Top + Pict(1).Height + GAP, _
  410.         wid, hgt
  411.     Pict(3).Move Pict(2).Left + Pict(2).Width + GAP, _
  412.         Pict(2).Top, wid, hgt
  413. End Sub
  414. ' ***********************************************
  415. ' Load a new image file.
  416. ' ***********************************************
  417. Private Sub mnuFileLoad_Click(Index As Integer)
  418. Dim fname As String
  419. Dim i As Integer
  420.     ' Allow the user to pick a file.
  421.     On Error Resume Next
  422.     FileDialog.filename = "*.BMP;*.ICO;*.RLE;*.WMF;*.DIB"
  423.     FileDialog.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  424.     FileDialog.ShowOpen
  425.     If Err.Number = cdlCancel Then
  426.         Exit Sub
  427.     ElseIf Err.Number <> 0 Then
  428.         Beep
  429.         MsgBox "Error selecting file.", , vbExclamation
  430.         Exit Sub
  431.     End If
  432.     On Error GoTo 0
  433.     fname = Trim$(FileDialog.filename)
  434.     FileDialog.InitDir = Left$(fname, Len(fname) _
  435.         - Len(FileDialog.FileTitle) - 1)
  436.     ' Load the picture.
  437.     WaitStart
  438.     LoadPict Index, fname
  439.         
  440.     ' Move each picture to the top so each can get
  441.     ' its color palette updated.
  442.     For i = 0 To 2
  443.         Pict(i).ZOrder
  444.         DoEvents
  445.     Next i
  446.     WaitEnd
  447. End Sub
  448. ' ***********************************************
  449. ' End the application. (See also the QueryUnload
  450. ' event.)
  451. ' ***********************************************
  452. Private Sub mnuFileExit_Click()
  453.     Unload Me
  454. End Sub
  455.