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

  1. VERSION 4.00
  2. Begin VB.Form CompositeForm2 
  3.    Caption         =   "Composite2"
  4.    ClientHeight    =   5895
  5.    ClientLeft      =   1215
  6.    ClientTop       =   585
  7.    ClientWidth     =   6510
  8.    Height          =   6300
  9.    Left            =   1155
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   393
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   434
  14.    Top             =   240
  15.    Width           =   6630
  16.    Begin VB.PictureBox DestPict 
  17.       AutoRedraw      =   -1  'True
  18.       AutoSize        =   -1  'True
  19.       Height          =   75
  20.       Left            =   6120
  21.       Picture         =   "COMPOSE2.frx":0000
  22.       ScaleHeight     =   1
  23.       ScaleMode       =   3  'Pixel
  24.       ScaleWidth      =   1
  25.       TabIndex        =   7
  26.       Top             =   1440
  27.       Visible         =   0   'False
  28.       Width           =   75
  29.    End
  30.    Begin VB.PictureBox Mask2Pict 
  31.       AutoRedraw      =   -1  'True
  32.       AutoSize        =   -1  'True
  33.       Height          =   75
  34.       Left            =   6120
  35.       Picture         =   "COMPOSE2.frx":0446
  36.       ScaleHeight     =   1
  37.       ScaleMode       =   3  'Pixel
  38.       ScaleWidth      =   1
  39.       TabIndex        =   6
  40.       Top             =   960
  41.       Visible         =   0   'False
  42.       Width           =   75
  43.    End
  44.    Begin VB.PictureBox Mask1Pict 
  45.       AutoRedraw      =   -1  'True
  46.       AutoSize        =   -1  'True
  47.       Height          =   75
  48.       Left            =   6120
  49.       Picture         =   "COMPOSE2.frx":088C
  50.       ScaleHeight     =   1
  51.       ScaleMode       =   3  'Pixel
  52.       ScaleWidth      =   1
  53.       TabIndex        =   5
  54.       Top             =   480
  55.       Visible         =   0   'False
  56.       Width           =   75
  57.    End
  58.    Begin VB.PictureBox SourcePict 
  59.       AutoRedraw      =   -1  'True
  60.       AutoSize        =   -1  'True
  61.       Height          =   75
  62.       Left            =   6120
  63.       Picture         =   "COMPOSE2.frx":0CD2
  64.       ScaleHeight     =   1
  65.       ScaleMode       =   3  'Pixel
  66.       ScaleWidth      =   1
  67.       TabIndex        =   4
  68.       Top             =   0
  69.       Visible         =   0   'False
  70.       Width           =   75
  71.    End
  72.    Begin VB.PictureBox DisplaySwin 
  73.       Height          =   5655
  74.       Left            =   0
  75.       ScaleHeight     =   373
  76.       ScaleMode       =   3  'Pixel
  77.       ScaleWidth      =   413
  78.       TabIndex        =   2
  79.       Top             =   0
  80.       Width           =   6255
  81.       Begin VB.PictureBox DisplayPict 
  82.          AutoRedraw      =   -1  'True
  83.          Height          =   5535
  84.          Left            =   0
  85.          Picture         =   "COMPOSE2.frx":1118
  86.          ScaleHeight     =   365
  87.          ScaleMode       =   3  'Pixel
  88.          ScaleWidth      =   405
  89.          TabIndex        =   3
  90.          Top             =   0
  91.          Width           =   6135
  92.       End
  93.    End
  94.    Begin VB.HScrollBar DisplayHBar 
  95.       Enabled         =   0   'False
  96.       Height          =   255
  97.       Left            =   0
  98.       TabIndex        =   1
  99.       Top             =   5640
  100.       Width           =   6285
  101.    End
  102.    Begin VB.VScrollBar DisplayVBar 
  103.       Enabled         =   0   'False
  104.       Height          =   5655
  105.       Left            =   6240
  106.       TabIndex        =   0
  107.       Top             =   0
  108.       Width           =   255
  109.    End
  110. Attribute VB_Name = "CompositeForm2"
  111. Attribute VB_Creatable = False
  112. Attribute VB_Exposed = False
  113. Option Explicit
  114. Dim SysPalSize As Integer
  115. Dim NumStaticColors As Integer
  116. Dim StaticColor1 As Integer
  117. Dim StaticColor2 As Integer
  118. Dim bytes_source() As Byte
  119. Dim bytes_dest() As Byte
  120. Dim bytes_mask1() As Byte
  121. Dim bytes_mask2() As Byte
  122. Dim wid(0 To 3) As Long
  123. Dim hgt(0 To 3) As Long
  124. Dim palentry(0 To 255) As PALETTEENTRY
  125. ' ************************************************
  126. ' Create and display the composite image.
  127. ' ************************************************
  128. Public Sub MakeComposite(xoff As Integer, yoff As Integer)
  129. Dim bound As Integer
  130. Dim mid_weight As Integer
  131. Dim xmin As Integer
  132. Dim ymin As Integer
  133. Dim xmax As Integer
  134. Dim ymax As Integer
  135. Dim x As Integer
  136. Dim y As Integer
  137. Dim black As Integer
  138. Dim white As Integer
  139. Dim status As Long
  140. Dim i As Integer
  141. Dim j As Integer
  142. Dim kernel() As Single
  143. Dim wgt As Single
  144. Dim bytes_mask1a() As Byte
  145. Dim r1 As Integer
  146. Dim r2 As Integer
  147. Dim dest_factor As Single
  148.     WaitStart
  149.     SourcePict.Visible = False
  150.     DestPict.Visible = False
  151.     Mask1Pict.Visible = False
  152.     Mask2Pict.Visible = False
  153.     ' See where source and destination overlap.
  154.     xmin = 1 + xoff
  155.     If xmin < 1 Then xmin = 1
  156.     ymin = 1 + yoff
  157.     If ymin < 1 Then ymin = 1
  158.     xmax = wid(0) + xoff
  159.     If xmax > wid(1) Then xmax = wid(1)
  160.     ymax = hgt(0) + yoff
  161.     If ymax > hgt(1) Then ymax = hgt(1)
  162.     ' Show the user what's going on.
  163.     DisplayPict.Move 0, 0, Mask1Pict.Width, Mask1Pict.Height
  164.     DoEvents
  165.     status = SetBitmapBits(DisplayPict.Image, wid(2) * hgt(2), bytes_mask1(1, 1))
  166.     DisplayPict.Refresh
  167.     ' Step 0: Combine the two masks into one.
  168.     white = StaticColor2 - 1
  169.     black = StaticColor1 + 1
  170.     For y = ymin To ymax
  171.         For x = xmin To xmax
  172.             If bytes_mask2(x, y) = black Then _
  173.                 bytes_mask1(x - xoff, y - yoff) = white
  174.         Next x
  175.     Next y
  176.     ' Show the user what's going on.
  177.     status = SetBitmapBits(DisplayPict.Image, wid(2) * hgt(2), bytes_mask1(1, 1))
  178.     DisplayPict.Refresh
  179.     ' Step 1: Low pass filter the source mask.
  180.     ' Create a 3x3 low pass kernel.
  181.     bound = 1
  182.     mid_weight = 1
  183.     ReDim kernel(-bound To bound, -bound To bound)
  184.     For i = -bound To bound
  185.         For j = -bound To bound
  186.             kernel(i, j) = 1
  187.         Next j
  188.     Next i
  189.     kernel(0, 0) = mid_weight
  190.     wgt = (2 * bound + 1) * (2 * bound + 1) - 1 + mid_weight
  191.     ' Apply the filter.
  192.     ReDim bytes_mask1a(1 To wid(2), 1 To hgt(2))
  193.     For y = bound + 1 To hgt(2) - bound
  194.         For x = bound + 1 To wid(2) - bound
  195.             r1 = 0
  196.             For i = -bound To bound
  197.                 For j = -bound To bound
  198.                     r1 = r1 + kernel(i, j) * palentry(bytes_mask1(x + i, y + j)).peRed
  199.                 Next j
  200.             Next i
  201.             r1 = r1 / wgt
  202.             bytes_mask1a(x, y) = NearestNonstaticGray(r1)
  203.         Next x
  204.     Next y
  205.     ' Blank the edges of the mask.
  206.     For y = 1 To hgt(2)
  207.         For x = 1 To bound
  208.             bytes_mask1a(x, y) = white
  209.             bytes_mask1a(wid(2) - x + 1, y) = white
  210.         Next x
  211.     Next y
  212.     For x = 1 To wid(2)
  213.         For y = 1 To bound
  214.             bytes_mask1a(x, y) = white
  215.             bytes_mask1a(x, hgt(2) - y + 1) = white
  216.         Next y
  217.     Next x
  218.     ' Show the user what's going on.
  219.     status = SetBitmapBits(DisplayPict.Image, wid(2) * hgt(2), bytes_mask1a(1, 1))
  220.     DisplayPict.Refresh
  221.     ' Take a weighted average of the two images
  222.     ' using the mask.
  223.     For y = ymin To ymax
  224.         For x = xmin To xmax
  225.             dest_factor = palentry(bytes_mask1a(x - xoff, y - yoff)).peRed / 255#
  226.             r1 = palentry(bytes_source(x - xoff, y - yoff)).peRed
  227.             r2 = palentry(bytes_dest(x, y)).peRed
  228.             bytes_dest(x, y) = NearestNonstaticGray((1 - dest_factor) * r1 + dest_factor * r2)
  229.         Next x
  230.     Next y
  231.     ' Display the result.
  232.     status = SetBitmapBits(DisplayPict.Image, wid(1) * hgt(1), bytes_dest(1, 1))
  233.     DisplayPict.Refresh
  234.     DisplayPict.Picture = DisplayPict.Image
  235.     ResetScrollBars
  236.     WaitEnd
  237.     ' This will definitely take a long time so
  238.     ' wake the user.
  239.     Beep
  240. End Sub
  241. ' ************************************************
  242. ' Return the index of the nonstatic gray closest
  243. ' to the given value (assuming the non-static
  244. ' colors are a gray scale created by
  245. ' MatchGrayPalette).
  246. ' ************************************************
  247. Function NearestNonstaticGray(c As Integer) As Integer
  248. Dim dgray As Single
  249.     If c < 0 Then
  250.         c = 0
  251.     ElseIf c > 255 Then
  252.         c = 255
  253.     End If
  254.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  255.     NearestNonstaticGray = c / dgray + StaticColor1 + 1
  256. End Function
  257. ' ***********************************************
  258. ' Load the indicated file and prepare to work
  259. ' with its palette. Return true if we cannot
  260. ' load the files.
  261. ' ***********************************************
  262. Public Function LoadFiles(source_name As String, dest_name As String, mask1_name As String, mask2_name As String) As Boolean
  263. Dim fname As String
  264. Dim i As Integer
  265.     WaitStart
  266.     LoadFiles = False
  267.     ' Create DisplayPict's palette.
  268.     MatchGrayPalette 0, DisplayPict, bytes_source
  269.     DoEvents    ' Don't be a total CPU hog.
  270.     ' Load the source file.
  271.     fname = source_name
  272.     SourcePict.Move 0, 0
  273.     SourcePict.Visible = True
  274.     On Error GoTo LoadFileError
  275.     SourcePict.Picture = LoadPicture(fname)
  276.     On Error GoTo 0
  277.     MatchGrayPalette 0, SourcePict, bytes_source
  278.     DoEvents    ' Don't be a total CPU hog.
  279.     ' Load the destination file.
  280.     fname = dest_name
  281.     DestPict.Move 0, 0
  282.     DestPict.Visible = True
  283.     On Error GoTo LoadFileError
  284.     DestPict.Picture = LoadPicture(fname)
  285.     On Error GoTo 0
  286.     MatchGrayPalette 1, DestPict, bytes_dest
  287.     DoEvents    ' Don't be a total CPU hog.
  288.     ' Load mask1.
  289.     fname = mask1_name
  290.     Mask1Pict.Move 0, 0
  291.     Mask1Pict.Visible = True
  292.     On Error GoTo LoadFileError
  293.     Mask1Pict.Picture = LoadPicture(fname)
  294.     On Error GoTo 0
  295.     MatchGrayPalette 2, Mask1Pict, bytes_mask1
  296.     DoEvents    ' Don't be a total CPU hog.
  297.     ' Load mask2.
  298.     fname = mask2_name
  299.     Mask2Pict.Move 0, 0
  300.     Mask2Pict.Visible = True
  301.     On Error GoTo LoadFileError
  302.     Mask2Pict.Picture = LoadPicture(fname)
  303.     On Error GoTo 0
  304.     MatchGrayPalette 3, Mask2Pict, bytes_mask2
  305.     DoEvents    ' Don't be a total CPU hog.
  306.     ' Rerealize each palette.
  307.     SourcePict.ZOrder
  308.     DoEvents
  309.     DestPict.ZOrder
  310.     DoEvents
  311.     Mask1Pict.ZOrder
  312.     DoEvents
  313.     Mask2Pict.ZOrder
  314.     DoEvents
  315.     WaitEnd
  316.     Exit Function
  317. LoadFileError:
  318.     Beep
  319.     MsgBox "Error loading file " & fname & "." & _
  320.         vbCrLf & Error$
  321.     WaitEnd
  322.     LoadFiles = True
  323.     Exit Function
  324. End Function
  325. ' ***********************************************
  326. ' Load the control's palette so the non-static
  327. ' colors are grays. Map the logical palette to
  328. ' match the system palette. Convert the image to
  329. ' use the non-static grays.
  330. ' Set the following module global variables.
  331. '   palentry()  Image logical palette entries.
  332. '   wid         Width of image.
  333. '   hgt         Height of image.
  334. '   bytes(1 To wid, 1 To hgt)
  335. '               Image pixel values.
  336. ' ***********************************************
  337. Sub MatchGrayPalette(Index As Integer, pic As Control, bytes() As Byte)
  338. Dim logpal As Integer
  339. Dim sys(0 To 255) As PALETTEENTRY
  340. Dim i As Integer
  341. Dim bm As BITMAP
  342. Dim hbm As Integer
  343. Dim status As Long
  344. Dim x As Integer
  345. Dim y As Integer
  346. Dim gray As Single
  347. Dim dgray As Single
  348. Dim c As Integer
  349. Dim clr As Integer
  350.     ' Make sure pic has the foreground palette.
  351.     pic.ZOrder
  352.     i = RealizePalette(pic.hdc)
  353.     DoEvents
  354.     ' Get the system palette entries.
  355.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  356.         
  357.     ' Get the image pixels.
  358.     hbm = pic.Image
  359.     status = GetObject(hbm, BITMAP_SIZE, bm)
  360.     wid(Index) = bm.bmWidthBytes
  361.     hgt(Index) = bm.bmHeight
  362.     ReDim bytes(1 To wid(Index), 1 To hgt(Index))
  363.     status = GetBitmapBits(hbm, wid(Index) * hgt(Index), bytes(1, 1))
  364.     ' Make the logical palette as big as possible.
  365.     logpal = pic.Picture.hPal
  366.     If ResizePalette(logpal, SysPalSize) = 0 Then
  367.         Beep
  368.         MsgBox "Error resizing logical palette.", _
  369.             vbExclamation
  370.         Exit Sub
  371.     End If
  372.     ' Blank the non-static colors.
  373.     For i = 0 To StaticColor1
  374.         palentry(i) = sys(i)
  375.     Next i
  376.     For i = StaticColor1 + 1 To StaticColor2 - 1
  377.         With palentry(i)
  378.             .peRed = 0
  379.             .peGreen = 0
  380.             .peBlue = 0
  381.             .peFlags = PC_NOCOLLAPSE
  382.         End With
  383.     Next i
  384.     For i = StaticColor2 To 255
  385.         palentry(i) = sys(i)
  386.     Next i
  387.     i = SetPaletteEntries(logpal, 0, SysPalSize, palentry(0))
  388.     ' Insert the non-static grays.
  389.     gray = 0
  390.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  391.     For i = StaticColor1 + 1 To StaticColor2 - 1
  392.         c = gray
  393.         gray = gray + dgray
  394.         With palentry(i)
  395.             .peRed = c
  396.             .peGreen = c
  397.             .peBlue = c
  398.         End With
  399.     Next i
  400.     i = SetPaletteEntries(logpal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, palentry(StaticColor1 + 1))
  401.     ' Recreate the image using the new colors.
  402.     For y = 1 To hgt(Index)
  403.         For x = 1 To wid(Index)
  404.             clr = bytes(x, y)
  405.             With sys(clr)
  406.                 c = (CInt(.peRed) + .peGreen + .peBlue) / 3
  407.             End With
  408.             bytes(x, y) = NearestNonstaticGray(c)
  409.         Next x
  410.     Next y
  411.     status = SetBitmapBits(hbm, wid(Index) * hgt(Index), bytes(1, 1))
  412.     ' Realize the gray palette.
  413.     i = RealizePalette(pic.hdc)
  414.     pic.Refresh
  415. End Sub
  416. ' ***********************************************
  417. ' Set the Max and LargeChange properties for the
  418. ' image scroll bars.
  419. ' ***********************************************
  420. Sub ResetScrollBars()
  421.     ' DisplayHBar.
  422.     DisplayHBar.Value = 0
  423.     If DisplaySwin.ScaleWidth >= DisplayPict.Width Then
  424.         DisplayHBar.Enabled = False
  425.     Else
  426.         DisplayHBar.Max = DisplayPict.Width - DisplaySwin.ScaleWidth
  427.         DisplayHBar.LargeChange = DisplaySwin.ScaleWidth
  428.         DisplayHBar.Enabled = True
  429.     End If
  430.     ' DisplayVBar.
  431.     DisplayVBar.Value = 0
  432.     If DisplaySwin.ScaleHeight >= DisplayPict.Height Then
  433.         DisplayVBar.Enabled = False
  434.     Else
  435.         DisplayVBar.Max = DisplayPict.Height - DisplaySwin.ScaleHeight
  436.         DisplayVBar.LargeChange = DisplaySwin.ScaleHeight
  437.         DisplayVBar.Enabled = True
  438.     End If
  439. End Sub
  440. ' ***********************************************
  441. ' Give the form and all the picture boxes an
  442. ' hourglass cursor.
  443. ' ***********************************************
  444. Sub WaitStart()
  445.     MousePointer = vbHourglass
  446.     DisplayPict.MousePointer = vbHourglass
  447.     SourcePict.MousePointer = vbHourglass
  448.     DestPict.MousePointer = vbHourglass
  449.     Mask1Pict.MousePointer = vbHourglass
  450.     Mask2Pict.MousePointer = vbHourglass
  451.     DoEvents
  452. End Sub
  453. ' ***********************************************
  454. ' Restore the mouse pointers for the form and all
  455. ' the picture boxes.
  456. ' ***********************************************
  457. Sub WaitEnd()
  458.     MousePointer = vbDefault
  459.     DisplayPict.MousePointer = vbDefault
  460.     SourcePict.MousePointer = vbDefault
  461.     DestPict.MousePointer = vbDefault
  462.     Mask1Pict.MousePointer = vbDefault
  463.     Mask2Pict.MousePointer = vbDefault
  464. End Sub
  465. Private Sub Form_Load()
  466.     ' Make sure the screen supports palettes.
  467.     If Not GetDeviceCaps(hdc, RASTERCAPS) And RC_PALETTE Then
  468.         Beep
  469.         MsgBox "This monitor does not support palettes.", _
  470.             vbCritical
  471.         End
  472.     End If
  473.     ' Get system palette size and # static colors.
  474.     SysPalSize = GetDeviceCaps(hdc, SIZEPALETTE)
  475.     NumStaticColors = GetDeviceCaps(hdc, NUMRESERVED)
  476.     StaticColor1 = NumStaticColors \ 2 - 1
  477.     StaticColor2 = SysPalSize - NumStaticColors \ 2
  478.     ' Remove the borders from DisplayPict.
  479.     DisplayPict.BorderStyle = vbTransparent
  480.     SourcePict.BorderStyle = vbTransparent
  481.     DestPict.BorderStyle = vbTransparent
  482.     Mask1Pict.BorderStyle = vbTransparent
  483.     Mask2Pict.BorderStyle = vbTransparent
  484. End Sub
  485. ' ***********************************************
  486. ' Make the picture as large as possible.
  487. ' ***********************************************
  488. Private Sub Form_Resize()
  489. Dim hgt As Single
  490. Dim wid As Single
  491.     If WindowState = vbMinimized Then Exit Sub
  492.         
  493.     hgt = ScaleHeight - DisplayHBar.Height - 1
  494.     wid = ScaleWidth - DisplayVBar.Width - 1
  495.     ' Place the controls.
  496.     DisplaySwin.Move 0, 0, wid, hgt
  497.     DisplayVBar.Move _
  498.         DisplaySwin.Left + DisplaySwin.Width + 1, _
  499.         0, DisplayVBar.Width, hgt
  500.     DisplayHBar.Move _
  501.         DisplaySwin.Left, DisplaySwin.Height + 1, _
  502.         wid
  503.     ' Set the scroll bar limits.
  504.     ResetScrollBars
  505. End Sub
  506. ' ***********************************************
  507. ' Move DisplayPict within DisplaySwin.
  508. ' ***********************************************
  509. Private Sub DisplayHBar_Change()
  510.     DisplayPict.Left = -DisplayHBar.Value
  511. End Sub
  512. ' ***********************************************
  513. ' Move DisplayPict within DisplaySwin.
  514. ' ***********************************************
  515. Private Sub DisplayHBar_Scroll()
  516.     DisplayPict.Left = -DisplayHBar.Value
  517. End Sub
  518. ' ***********************************************
  519. ' Move DisplayPict within DisplaySwin.
  520. ' ***********************************************
  521. Private Sub DisplayVBar_Change()
  522.     DisplayPict.Top = -DisplayVBar.Value
  523. End Sub
  524. ' ***********************************************
  525. ' Move DisplayPict within DisplaySwin.
  526. ' ***********************************************
  527. Private Sub DisplayVBar_Scroll()
  528.     DisplayPict.Top = -DisplayVBar.Value
  529. End Sub
  530. Private Sub Form_Unload(Cancel As Integer)
  531.     End
  532. End Sub
  533.