home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / ID_Card_Ma2071636202007.psc / cDIBSection.cls < prev    next >
Text File  |  1999-09-07  |  16KB  |  469 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "cDIBSection"
  6. Attribute VB_GlobalNameSpace = False
  7. Attribute VB_Creatable = True
  8. Attribute VB_PredeclaredId = False
  9. Attribute VB_Exposed = False
  10. Option Explicit
  11.  
  12. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
  13.     lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
  14.  
  15. Private Type SAFEARRAYBOUND
  16.     cElements As Long
  17.     lLbound As Long
  18. End Type
  19. Private Type SAFEARRAY2D
  20.     cDims As Integer
  21.     fFeatures As Integer
  22.     cbElements As Long
  23.     cLocks As Long
  24.     pvData As Long
  25.     Bounds(0 To 1) As SAFEARRAYBOUND
  26. End Type
  27. Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long
  28.  
  29. Private Type RGBQUAD
  30.     rgbBlue As Byte
  31.     rgbGreen As Byte
  32.     rgbRed As Byte
  33.     rgbReserved As Byte
  34. End Type
  35. Private Type BITMAPINFOHEADER '40 bytes
  36.     biSize As Long
  37.     biWidth As Long
  38.     biHeight As Long
  39.     biPlanes As Integer
  40.     biBitCount As Integer
  41.     biCompression As Long
  42.     biSizeImage As Long
  43.     biXPelsPerMeter As Long
  44.     biYPelsPerMeter As Long
  45.     biClrUsed As Long
  46.     biClrImportant As Long
  47. End Type
  48. Private Type BITMAPINFO
  49.     bmiHeader As BITMAPINFOHEADER
  50.     bmiColors As RGBQUAD
  51. End Type
  52. Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
  53. Private Declare Function GetDC Lib "USER32" (ByVal hwnd As Long) As Long
  54. Private Declare Function GetDesktopWindow Lib "USER32" () As Long
  55. ' Note - this is not the declare in the API viewer - modify lplpVoid to be
  56. ' Byref so we get the pointer back:
  57. Private Declare Function CreateDIBSection Lib "gdi32" _
  58.     (ByVal hdc As Long, _
  59.     pBitmapInfo As BITMAPINFO, _
  60.     ByVal un As Long, _
  61.     lplpVoid As Long, _
  62.     ByVal handle As Long, _
  63.     ByVal dw As Long) As Long
  64. Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
  65. Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
  66. Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
  67. Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
  68. Private Declare Function ReleaseDC Lib "USER32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
  69. Private Declare Function LoadImage Lib "USER32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
  70. Private Const BI_RGB = 0&
  71. Private Const BI_RLE4 = 2&
  72. Private Const BI_RLE8 = 1&
  73. Private Const DIB_RGB_COLORS = 0 '  color table in RGBs
  74.  
  75. Private Type BITMAP
  76.     bmType As Long
  77.     bmWidth As Long
  78.     bmHeight As Long
  79.     bmWidthBytes As Long
  80.     bmPlanes As Integer
  81.     bmBitsPixel As Integer
  82.     bmBits As Long
  83. End Type
  84. Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
  85. Private Declare Function timeGetTime Lib "winmm.dll" () As Long
  86. Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
  87.  
  88. ' Clipboard functions:
  89. Private Declare Function OpenClipboard Lib "USER32" (ByVal hwnd As Long) As Long
  90. Private Declare Function CloseClipboard Lib "USER32" () As Long
  91. Private Declare Function SetClipboardData Lib "USER32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
  92. Private Declare Function EmptyClipboard Lib "USER32" () As Long
  93. Private Const CF_BITMAP = 2
  94. Private Const CF_DIB = 8
  95.  
  96. ' Handle to the current DIBSection:
  97. Private m_hDIb As Long
  98. ' Handle to the old bitmap in the DC, for clear up:
  99. Private m_hBmpOld As Long
  100. ' Handle to the Device context holding the DIBSection:
  101. Private m_hDC As Long
  102. ' Address of memory pointing to the DIBSection's bits:
  103. Private m_lPtr As Long
  104. ' Type containing the Bitmap information:
  105. Private m_tBI As BITMAPINFO
  106.  
  107. Public Function CopyToClipboard( _
  108.         Optional ByVal bAsDIB As Boolean = True _
  109.     ) As Boolean
  110. Dim lhDCDesktop As Long
  111. Dim lhDC As Long
  112. Dim lhBmpOld As Long
  113. Dim hObj As Long
  114. Dim lFmt As Long
  115. Dim b() As Byte
  116. Dim tBI As BITMAPINFO
  117. Dim lPtr As Long
  118. Dim hDibCopy As Long
  119.  
  120.     lhDCDesktop = GetDC(GetDesktopWindow())
  121.     If (lhDCDesktop <> 0) Then
  122.         lhDC = CreateCompatibleDC(lhDCDesktop)
  123.         If (lhDC <> 0) Then
  124.             If (bAsDIB) Then
  125.                MsgBox "I don't know how to put a DIB on the clipboard! Copy as bitmap instead!!!"
  126.                 ' Create a duplicate DIBSection and copy
  127.                 ' to the clipboard:
  128.                 'LSet tBI = m_tBI
  129.                 'hDibCopy = CreateDIBSection( _
  130.                 '        lhDC, _
  131.                 '        m_tBI, _
  132.                 '        DIB_RGB_COLORS, _
  133.                 '        lPtr, _
  134.                 '        0, 0)
  135.                 'If (hDibCopy <> 0) Then
  136.                 '    lhBmpOld = SelectObject(lhDC, hObj)
  137.                 '    BitBlt lhDC, 0, 0, Width, Height, m_hDC, 0, 0, vbSrcCopy
  138.                 '    SelectObject lhDC, lhBmpOld
  139.                 '    lFmt = CF_DIB
  140.                 '
  141.                 '     '....
  142.                                     
  143.                 'Else
  144.                 '    hObj = 0
  145.                 'End If
  146.             Else
  147.                 ' Create a compatible bitmap and copy to
  148.                 ' the clipboard:
  149.                 hObj = CreateCompatibleBitmap(lhDCDesktop, Width, Height)
  150.                 If (hObj <> 0) Then
  151.                     lhBmpOld = SelectObject(lhDC, hObj)
  152.                     PaintPicture lhDC
  153.                     SelectObject lhDC, lhBmpOld
  154.                     lFmt = CF_BITMAP
  155.                     ' Now set the clipboard to the bitmap:
  156.                     If (OpenClipboard(0) <> 0) Then
  157.                         EmptyClipboard
  158.                         If (SetClipboardData(lFmt, hObj) <> 0) Then
  159.                             CopyToClipboard = True
  160.                         End If
  161.                         CloseClipboard
  162.                     End If
  163.                 End If
  164.             End If
  165.             DeleteDC lhDC
  166.         End If
  167.         DeleteDC lhDCDesktop
  168.     End If
  169. End Function
  170.  
  171. Public Function CreateDIB( _
  172.         ByVal lhDC As Long, _
  173.         ByVal lWidth As Long, _
  174.         ByVal lHeight As Long, _
  175.         ByRef hDib As Long _
  176.     ) As Boolean
  177.     With m_tBI.bmiHeader
  178.         .biSize = Len(m_tBI.bmiHeader)
  179.         .biWidth = lWidth
  180.         .biHeight = lHeight
  181.         .biPlanes = 1
  182.         .biBitCount = 24
  183.         .biCompression = BI_RGB
  184.         .biSizeImage = BytesPerScanLine * .biHeight
  185.     End With
  186.     hDib = CreateDIBSection( _
  187.             lhDC, _
  188.             m_tBI, _
  189.             DIB_RGB_COLORS, _
  190.             m_lPtr, _
  191.             0, 0)
  192.     CreateDIB = (hDib <> 0)
  193. End Function
  194. Public Function CreateFromPicture( _
  195.         ByRef picThis As StdPicture _
  196.     )
  197. Dim lhDC As Long
  198. Dim lhDCDesktop As Long
  199. Dim lhBmpOld As Long
  200. Dim tBMP As BITMAP
  201. Dim lhWnd As Long
  202.     
  203.     GetObjectAPI picThis.handle, Len(tBMP), tBMP
  204.     If (Create(tBMP.bmWidth, tBMP.bmHeight)) Then
  205.         lhWnd = GetDesktopWindow()
  206.         lhDCDesktop = GetDC(lhWnd)
  207.         If (lhDCDesktop <> 0) Then
  208.             lhDC = CreateCompatibleDC(lhDCDesktop)
  209.             ReleaseDC lhWnd, lhDCDesktop
  210.             If (lhDC <> 0) Then
  211.                 lhBmpOld = SelectObject(lhDC, picThis.handle)
  212.                 LoadPictureBlt lhDC
  213.                 SelectObject lhDC, lhBmpOld
  214.                 DeleteDC lhDC
  215.             End If
  216.         End If
  217.     End If
  218. End Function
  219. Public Function Create( _
  220.         ByVal lWidth As Long, _
  221.         ByVal lHeight As Long _
  222.     ) As Boolean
  223.     ClearUp
  224.     m_hDC = CreateCompatibleDC(0)
  225.     If (m_hDC <> 0) Then
  226.         If (CreateDIB(m_hDC, lWidth, lHeight, m_hDIb)) Then
  227.             m_hBmpOld = SelectObject(m_hDC, m_hDIb)
  228.             Create = True
  229.         Else
  230.             DeleteDC m_hDC
  231.             m_hDC = 0
  232.         End If
  233.     End If
  234. End Function
  235. Public Property Get BytesPerScanLine() As Long
  236.     ' Scans must align on dword boundaries:
  237.     BytesPerScanLine = (m_tBI.bmiHeader.biWidth * 3 + 3) And &HFFFFFFFC
  238. End Property
  239.  
  240. Public Property Get Width() As Long
  241.     Width = m_tBI.bmiHeader.biWidth
  242. End Property
  243. Public Property Get Height() As Long
  244.     Height = m_tBI.bmiHeader.biHeight
  245. End Property
  246.  
  247. Public Sub LoadPictureBlt( _
  248.         ByVal lhDC As Long, _
  249.         Optional ByVal lSrcLeft As Long = 0, _
  250.         Optional ByVal lSrcTop As Long = 0, _
  251.         Optional ByVal lSrcWidth As Long = -1, _
  252.         Optional ByVal lSrcHeight As Long = -1, _
  253.         Optional ByVal eRop As RasterOpConstants = vbSrcCopy _
  254.     )
  255.     If lSrcWidth < 0 Then lSrcWidth = m_tBI.bmiHeader.biWidth
  256.     If lSrcHeight < 0 Then lSrcHeight = m_tBI.bmiHeader.biHeight
  257.     BitBlt m_hDC, 0, 0, lSrcWidth, lSrcHeight, lhDC, lSrcLeft, lSrcTop, eRop
  258. End Sub
  259.  
  260.  
  261. Public Sub PaintPicture( _
  262.         ByVal lhDC As Long, _
  263.         Optional ByVal lDestLeft As Long = 0, _
  264.         Optional ByVal lDestTop As Long = 0, _
  265.         Optional ByVal lDestWidth As Long = -1, _
  266.         Optional ByVal lDestHeight As Long = -1, _
  267.         Optional ByVal lSrcLeft As Long = 0, _
  268.         Optional ByVal lSrcTop As Long = 0, _
  269.         Optional ByVal eRop As RasterOpConstants = vbSrcCopy _
  270.     )
  271.     If (lDestWidth < 0) Then lDestWidth = m_tBI.bmiHeader.biWidth
  272.     If (lDestHeight < 0) Then lDestHeight = m_tBI.bmiHeader.biHeight
  273.     BitBlt lhDC, lDestLeft, lDestTop, lDestWidth, lDestHeight, m_hDC, lSrcLeft, lSrcTop, eRop
  274. End Sub
  275.  
  276. Public Property Get hdc() As Long
  277.     hdc = m_hDC
  278. End Property
  279. Public Property Get hDib() As Long
  280.     hDib = m_hDIb
  281. End Property
  282. Public Property Get DIBSectionBitsPtr() As Long
  283.     DIBSectionBitsPtr = m_lPtr
  284. End Property
  285. Public Sub RandomiseBits( _
  286.         Optional ByVal bGray As Boolean = False _
  287.     )
  288. Dim bDib() As Byte
  289. Dim x As Long, y As Long
  290. Dim lC As Long
  291. Dim tSA As SAFEARRAY2D
  292. Dim xEnd As Long
  293.     
  294.     ' Get the bits in the from DIB section:
  295.     With tSA
  296.         .cbElements = 1
  297.         .cDims = 2
  298.         .Bounds(0).lLbound = 0
  299.         .Bounds(0).cElements = m_tBI.bmiHeader.biHeight
  300.         .Bounds(1).lLbound = 0
  301.         .Bounds(1).cElements = BytesPerScanLine()
  302.         .pvData = m_lPtr
  303.     End With
  304.     CopyMemory ByVal VarPtrArray(bDib()), VarPtr(tSA), 4
  305.  
  306.     ' random:
  307.     Randomize Timer
  308.     
  309.     xEnd = (Width - 1) * 3
  310.     If (bGray) Then
  311.         For y = 0 To m_tBI.bmiHeader.biHeight - 1
  312.             For x = 0 To xEnd Step 3
  313.                 lC = Rnd * 255
  314.                 bDib(x, y) = lC
  315.                 bDib(x + 1, y) = lC
  316.                 bDib(x + 2, y) = lC
  317.             Next x
  318.         Next y
  319.     Else
  320.         For x = 0 To xEnd Step 3
  321.             For y = 0 To m_tBI.bmiHeader.biHeight - 1
  322.                 bDib(x, y) = 0
  323.                 bDib(x + 1, y) = Rnd * 255
  324.                 bDib(x + 2, y) = Rnd * 255
  325.             Next y
  326.         Next x
  327.     End If
  328.     
  329.     ' Clear the temporary array descriptor
  330.     ' (This does not appear to be necessary, but
  331.     ' for safety do it anyway)
  332.     CopyMemory ByVal VarPtrArray(bDib), 0&, 4
  333.     
  334. End Sub
  335.  
  336. Public Sub ClearUp()
  337.     If (m_hDC <> 0) Then
  338.         If (m_hDIb <> 0) Then
  339.             SelectObject m_hDC, m_hBmpOld
  340.             DeleteObject m_hDIb
  341.         End If
  342.         DeleteDC m_hDC
  343.     End If
  344.     m_hDC = 0: m_hDIb = 0: m_hBmpOld = 0: m_lPtr = 0
  345. End Sub
  346.  
  347. Public Function Resample( _
  348.         ByVal lNewHeight As Long, _
  349.         ByVal lNewWidth As Long _
  350.     ) As cDIBSection
  351. Dim cDib As cDIBSection
  352.     Set cDib = New cDIBSection
  353.     If cDib.Create(lNewWidth, lNewHeight) Then
  354.         If (lNewWidth <> m_tBI.bmiHeader.biWidth) Or (lNewHeight <> m_tBI.bmiHeader.biHeight) Then
  355.             ' Change in size, do resample:
  356.             ResampleDib cDib
  357.         Else
  358.             ' No size change so just return a copy:
  359.             cDib.LoadPictureBlt m_hDC
  360.         End If
  361.         Set Resample = cDib
  362.     End If
  363. End Function
  364.  
  365. Private Function ResampleDib(ByRef cDibTo As cDIBSection) As Boolean
  366. Dim bDibFrom() As Byte
  367. Dim bDibTo() As Byte
  368.  
  369. Dim tSAFrom As SAFEARRAY2D
  370. Dim tSATo As SAFEARRAY2D
  371.  
  372.     ' Get the bits in the from DIB section:
  373.     With tSAFrom
  374.         .cbElements = 1
  375.         .cDims = 2
  376.         .Bounds(0).lLbound = 0
  377.         .Bounds(0).cElements = m_tBI.bmiHeader.biHeight
  378.         .Bounds(1).lLbound = 0
  379.         .Bounds(1).cElements = BytesPerScanLine()
  380.         .pvData = m_lPtr
  381.     End With
  382.     CopyMemory ByVal VarPtrArray(bDibFrom()), VarPtr(tSAFrom), 4
  383.  
  384.     ' Get the bits in the to DIB section:
  385.     With tSATo
  386.         .cbElements = 1
  387.         .cDims = 2
  388.         .Bounds(0).lLbound = 0
  389.         .Bounds(0).cElements = cDibTo.Height
  390.         .Bounds(1).lLbound = 0
  391.         .Bounds(1).cElements = cDibTo.BytesPerScanLine()
  392.         .pvData = cDibTo.DIBSectionBitsPtr
  393.     End With
  394.     CopyMemory ByVal VarPtrArray(bDibTo()), VarPtr(tSATo), 4
  395.  
  396. Dim xScale As Single
  397. Dim yScale As Single
  398.  
  399. Dim x As Long, y As Long, xEnd As Long, xOut As Long
  400.  
  401. Dim fX As Single, fY As Single
  402. Dim ifY As Long, ifX As Long
  403. Dim dX As Single, dy As Single
  404. Dim r As Long, r1 As Single, r2 As Single, r3 As Single, r4 As Single
  405. Dim g As Long, g1 As Single, g2 As Single, g3 As Single, g4 As Single
  406. Dim b As Long, b1 As Single, b2 As Single, b3 As Single, b4 As Single
  407. Dim ir1 As Long, ig1 As Long, ib1 As Long
  408. Dim ir2 As Long, ig2 As Long, ib2 As Long
  409.  
  410.     xScale = (Width - 1) / cDibTo.Width
  411.     yScale = (Height - 1) / cDibTo.Height
  412.     
  413.     xEnd = cDibTo.Width - 1
  414.         
  415.     For y = 0 To cDibTo.Height - 1
  416.         
  417.         fY = y * yScale
  418.         ifY = Int(fY)
  419.         dy = fY - ifY
  420.         
  421.         For x = 0 To xEnd
  422.             fX = x * xScale
  423.             ifX = Int(fX)
  424.             dX = fX - ifX
  425.             
  426.             ifX = ifX * 3
  427.             ' Interpolate using the four nearest pixels in the source
  428.             b1 = bDibFrom(ifX, ifY): g1 = bDibFrom(ifX + 1, ifY): r1 = bDibFrom(ifX + 2, ifY)
  429.             b2 = bDibFrom(ifX + 3, ifY): g2 = bDibFrom(ifX + 4, ifY): r2 = bDibFrom(ifX + 5, ifY)
  430.             b3 = bDibFrom(ifX, ifY + 1): g3 = bDibFrom(ifX + 1, ifY + 1): r3 = bDibFrom(ifX + 2, ifY + 1)
  431.             b4 = bDibFrom(ifX + 3, ifY + 1): g4 = bDibFrom(ifX + 4, ifY + 1): r4 = bDibFrom(ifX + 5, ifY + 1)
  432.             
  433.             ' Interplate in x direction:
  434.             ir1 = r1 * (1 - dy) + r3 * dy: ig1 = g1 * (1 - dy) + g3 * dy: ib1 = b1 * (1 - dy) + b3 * dy
  435.             ir2 = r2 * (1 - dy) + r4 * dy: ig2 = g2 * (1 - dy) + g4 * dy: ib2 = b2 * (1 - dy) + b4 * dy
  436.             ' Interpolate in y:
  437.             r = ir1 * (1 - dX) + ir2 * dX: g = ig1 * (1 - dX) + ig2 * dX: b = ib1 * (1 - dX) + ib2 * dX
  438.             
  439.             ' Set output:
  440.             If (r < 0) Then r = 0
  441.             If (r > 255) Then r = 255
  442.             If (g < 0) Then g = 0
  443.             If (g > 255) Then g = 255
  444.             If (b < 0) Then b = 0
  445.             If (b > 255) Then
  446.                 b = 255
  447.             End If
  448.             xOut = x * 3
  449.             bDibTo(xOut, y) = b
  450.             bDibTo(xOut + 1, y) = g
  451.             bDibTo(xOut + 2, y) = r
  452.             
  453.         Next x
  454.         
  455.     Next y
  456.  
  457.     ' Clear the temporary array descriptor
  458.     ' (This does not appear to be necessary, but
  459.     ' for safety do it anyway)
  460.     CopyMemory ByVal VarPtrArray(bDibFrom), 0&, 4
  461.     CopyMemory ByVal VarPtrArray(bDibTo), 0&, 4
  462.  
  463.  
  464. End Function
  465.  
  466. Private Sub Class_Terminate()
  467.     ClearUp
  468. End Sub
  469.