home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / Real-time_2028201112006.psc / FastDrawing.cls < prev    next >
Text File  |  2006-07-29  |  14KB  |  281 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "FastDrawing"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15. '***************************************************************************
  16. 'Real-time drawing class for Visual Basic 5.0/6.0
  17. '⌐2002-2006 Tanner 'DemonSpectre' Helland
  18. 'Created: 10/03/01
  19. 'Last updated: 19/July/06
  20. 'Last update: Added 2D array conversions, added OriginalWidth/Height requirements
  21. '             for setting image data
  22. 'Notes: The OriginalWidth/Height requirements have been added to circumvent errors
  23. '       generated when programmers attempt to capture data from one picture box
  24. '       and assign it to one with a different size.  That should be okay now - the
  25. '       image will just be stretched to the size of the new box, rather than
  26. '       crashing like before.
  27. '
  28. 'This class is every graphics programmers dream - it does all the dirty API
  29. 'work required for lightning fast graphics, and all you have to do is call a
  30. 'couple of routines.  Am I a nice guy or what?  The format is simple; the only
  31. 'variables either of the subs require is the picture box you're going to do
  32. 'the image processing work on and an array to store the information in.  This is
  33. 'about as simple as it gets.  If you can't figure out how to use this module, maybe
  34. 'programming isn't the thing for you. ;)
  35. '
  36. '---------------
  37. 'TERMS OF USE:
  38. 'Feel free to compile this class into any executable of your own, but be
  39. 'sure to give me credit somewhere (and please notify me; I love hearing how
  40. 'this code helps fellow programmers out, and I find myself more motivated to
  41. 'contribute to the online programming community if I get feedback).
  42. '
  43. 'DO NOT, however, upload or reproduce this particular class module to any website or
  44. 'other form of publicly available media.  If you would like to include this code as
  45. 'part of a personal project that will be distributed in code form, you MUST OBTAIN
  46. 'PERMISSION FROM ME.  This is for two reasons - one, to ensure that some idiot
  47. 'doesn't try to take credit for work he/she didn't do, and - two - to prevent faulty
  48. 'code from being distributed with my name attatched to it.  Several years ago I had
  49. 'a programmer from a foreign country try to redistribute this very code (with a
  50. 'similar brightness routine written by me) except that he had modified it so it
  51. 'didn't work correctly.  Stuff like that pisses me off beyond all compare.
  52. 'Eventually we were able to sort the problem out, but not before several hundred
  53. 'people downloaded faulty code with my name attatched to it.  So CONTACT ME BEFORE
  54. 'DISTRIBUTING THIS CODE IN A PUBLIC SETTING.
  55. '
  56. 'Also, if you use these routines as part of a dll or ocx project, THEY CANNOT BE
  57. 'PART OF A PUBLIC ROUTINE.  They must be declared privately (i.e. not available
  58. 'to the end user).
  59. '
  60. 'Lastly, I accept NO LEGAL RESPONSIBILITY for any problems that arise from use of
  61. 'this code.  Use it at your own risk.  A similar warning appears on my website, so
  62. 'you're on your own if this somehow breaks stuff.  It shouldn't, but the API is a
  63. 'vast wonderland of errors - so consider yourself warned.
  64. '---------------
  65. '
  66. 'Hopefully this code will be of some help to you.  If for any reason you do happen
  67. 'to encounter problems with this class, please let me know about them and I'll see
  68. 'if I can't help you out.
  69. '
  70. 'Best regards,
  71. '
  72. '-Tanner 'DemonSpectre' Helland
  73. 'tannerhelland@hotmail.com
  74. 'http://www.tannerhelland.com
  75. 'http://www.studentsofgamedesign.com
  76. '***************************************************************************
  77.  
  78. 'Stripped down bitmap information
  79. Private Type Bitmap
  80.     bmType As Long
  81.     bmWidth As Long
  82.     bmHeight As Long
  83.     bmWidthBytes As Long
  84.     bmPlanes As Integer
  85.     bmBitsPixel As Integer
  86.     bmBits As Long
  87. End Type
  88. 'Call to transfer an object's properties into a custom variable
  89. Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
  90. 'Standard pixel data
  91. Private Type RGBQUAD
  92.         rgbBlue As Byte
  93.         rgbGreen As Byte
  94.         rgbRed As Byte
  95.         rgbAlpha As Byte
  96. End Type
  97. 'Full-size bitmap header
  98. Private Type BITMAPINFOHEADER
  99.         bmSize As Long
  100.         bmWidth As Long
  101.         bmHeight As Long
  102.         bmPlanes As Integer
  103.         bmBitCount As Integer
  104.         bmCompression As Long
  105.         bmSizeImage As Long
  106.         bmXPelsPerMeter As Long
  107.         bmYPelsPerMeter As Long
  108.         bmClrUsed As Long
  109.         bmClrImportant As Long
  110. End Type
  111. 'Extended header for 8-bit images
  112. Private Type BITMAPINFO
  113.         bmHeader As BITMAPINFOHEADER
  114.         bmColors(0 To 255) As RGBQUAD
  115. End Type
  116.  
  117. 'DIB section interfaces
  118. Private Declare Function GetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
  119. Private Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dX As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal SrcWidth As Long, ByVal SrcHeight As Long, lpBits As Any, lpBitsInfo As BITMAPINFO, ByVal wUsage As Long, ByVal dwRop As Long) As Long
  120.  
  121. 'Get the image width (via API - always accurate, unlike PictureBox.ScaleWidth)
  122. Public Function GetImageWidth(SrcPictureBox As PictureBox) As Long
  123.     Dim bm As Bitmap
  124.     GetObject SrcPictureBox.Image, Len(bm), bm
  125.     GetImageWidth = bm.bmWidth
  126. End Function
  127.  
  128. 'Get the image height (via API - always accurate)
  129. Public Function GetImageHeight(SrcPictureBox As PictureBox) As Long
  130.     Dim bm As Bitmap
  131.     GetObject SrcPictureBox.Image, Len(bm), bm
  132.     GetImageHeight = bm.bmHeight
  133. End Function
  134.  
  135. 'Get the stream length of an image (via API - always accurate)
  136. Public Function GetImageStreamLength(SrcPictureBox As PictureBox) As Long
  137.     Dim bm As Bitmap
  138.     GetObject SrcPictureBox.Image, Len(bm), bm
  139.     GetImageStreamLength = (bm.bmWidth * (bm.bmHeight + 1)) * 3
  140. End Function
  141.  
  142. 'Added 19/July/2006
  143. 'Get an image's pixel information into an array dimensioned (x * 3 + bgr, y)
  144. Public Sub GetImageData2D(SrcPictureBox As PictureBox, ImageData() As Byte)
  145.     Dim bm As Bitmap
  146.     'Get the picture box information
  147.     GetObject SrcPictureBox.Image, Len(bm), bm
  148.     'Build a correctly sized array
  149.     Erase ImageData()
  150.     'Generate a correctly-dimensioned array (for 2-dimensional access)
  151.     Dim ArrayWidth As Long
  152.     ArrayWidth = (bm.bmWidth * 3) - 1
  153.     ArrayWidth = ArrayWidth + (bm.bmWidth Mod 4)  '4-bit alignment
  154.     ReDim ImageData(0 To ArrayWidth, 0 To bm.bmHeight) As Byte
  155.     'Create a temporary header to pass to the GetDIBits call
  156.     Dim bmi As BITMAPINFO
  157.     bmi.bmHeader.bmWidth = bm.bmWidth
  158.     bmi.bmHeader.bmHeight = bm.bmHeight
  159.     bmi.bmHeader.bmSize = 40                'Size, in bytes, of the header
  160.     bmi.bmHeader.bmPlanes = 1               'Number of planes (always one for this instance)
  161.     bmi.bmHeader.bmBitCount = 24            'Bits per pixel (always 24 for this instance)
  162.     bmi.bmHeader.bmCompression = 0          'Compression :standard/none or RLE
  163.     'Get the image data into our array
  164.     GetDIBits SrcPictureBox.hdc, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0), bmi, 0
  165.  
  166. End Sub
  167.  
  168. 'Added 19/July/2006
  169. 'Set an image's pixel information from an array dimensioned (x * 3 + bgr, y)
  170. Public Sub SetImageData2D(DstPictureBox As PictureBox, OriginalWidth As Long, OriginalHeight As Long, ImageData() As Byte)
  171.     Dim bm As Bitmap
  172.     'Get the picture box information
  173.     GetObject DstPictureBox.Image, Len(bm), bm
  174.     'Create a temporary header to pass to the StretchDIBits call
  175.     Dim bmi As BITMAPINFO
  176.     bmi.bmHeader.bmWidth = OriginalWidth
  177.     bmi.bmHeader.bmHeight = OriginalHeight
  178.     bmi.bmHeader.bmSize = 40                'Size, in bytes, of the header
  179.     bmi.bmHeader.bmPlanes = 1               'Number of planes (always one for this instance)
  180.     bmi.bmHeader.bmBitCount = 24            'Bits per pixel (always 24 for this instance)
  181.     bmi.bmHeader.bmCompression = 0          'Compression :standard/none or RLE
  182.     'Send the array to the picture box and draw it accordingly
  183.     StretchDIBits DstPictureBox.hdc, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, OriginalWidth, OriginalHeight, ImageData(0, 0), bmi, 0, vbSrcCopy
  184.     'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
  185.     If DstPictureBox.AutoRedraw = True Then
  186.         DstPictureBox.Picture = DstPictureBox.Image
  187.         DstPictureBox.Refresh
  188.     End If
  189.     'Always good to manually halt for external processes after heavy API usage
  190.     DoEvents
  191. End Sub
  192.  
  193. 'Get an image's pixel information into an array dimensioned (r/g/b, x, y)
  194. Public Sub GetImageData(SrcPictureBox As PictureBox, ImageData() As Byte)
  195.     Dim bm As Bitmap
  196.     'Get the picture box information
  197.     GetObject SrcPictureBox.Image, Len(bm), bm
  198.     'Build a correctly sized array
  199.     Erase ImageData()
  200.     ReDim ImageData(0 To 2, 0 To bm.bmWidth - 1, 0 To bm.bmHeight - 1)
  201.     'Create a temporary header to pass to the GetDIBits call
  202.     Dim bmi As BITMAPINFO
  203.     bmi.bmHeader.bmWidth = bm.bmWidth
  204.     bmi.bmHeader.bmHeight = bm.bmHeight
  205.     bmi.bmHeader.bmSize = 40                'Size, in bytes, of the header
  206.     bmi.bmHeader.bmPlanes = 1               'Number of planes (always one for this instance)
  207.     bmi.bmHeader.bmBitCount = 24            'Bits per pixel (always 24 for this instance)
  208.     bmi.bmHeader.bmCompression = 0          'Compression :standard/none or RLE
  209.     'Get the image data into our array
  210.     GetDIBits SrcPictureBox.hdc, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0, 0), bmi, 0
  211. End Sub
  212.  
  213. 'Set an image's pixel information from an array dimensioned (r/g/b, x, y)
  214. Public Sub SetImageData(DstPictureBox As PictureBox, OriginalWidth As Long, OriginalHeight As Long, ImageData() As Byte)
  215.     Dim bm As Bitmap
  216.     'Get the picture box information
  217.     GetObject DstPictureBox.Image, Len(bm), bm
  218.     'Create a temporary header to pass to the StretchDIBits call
  219.     Dim bmi As BITMAPINFO
  220.     bmi.bmHeader.bmWidth = OriginalWidth
  221.     bmi.bmHeader.bmHeight = OriginalHeight
  222.     bmi.bmHeader.bmSize = 40                'Size, in bytes, of the header
  223.     bmi.bmHeader.bmPlanes = 1               'Number of planes (always one for this instance)
  224.     bmi.bmHeader.bmBitCount = 24            'Bits per pixel (always 24 for this instance)
  225.     bmi.bmHeader.bmCompression = 0          'Compression :standard/none or RLE
  226.     'Send the array to the picture box and draw it accordingly
  227.     StretchDIBits DstPictureBox.hdc, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, OriginalWidth, OriginalHeight, ImageData(0, 0, 0), bmi, 0, vbSrcCopy
  228.     'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
  229.     If DstPictureBox.AutoRedraw = True Then
  230.         DstPictureBox.Picture = DstPictureBox.Image
  231.         DstPictureBox.Refresh
  232.     End If
  233.     'Always good to manually halt for external processes after heavy API usage
  234.     DoEvents
  235. End Sub
  236.  
  237. 'Get an image's pixel data into a one-dimesional array (stream)
  238. Public Sub GetImageDataStream(SrcPictureBox As PictureBox, ImageData() As Byte)
  239.     Dim bm As Bitmap
  240.     'Get the picture box information
  241.     GetObject SrcPictureBox.Image, Len(bm), bm
  242.     'Build a correctly sized array - in this case, designed as a stream
  243.     Erase ImageData()
  244.     ReDim ImageData(0 To GetImageStreamLength(SrcPictureBox))
  245.     'Create a temporary header to pass to the GetDIBits call
  246.     Dim bmi As BITMAPINFO
  247.     bmi.bmHeader.bmWidth = bm.bmWidth
  248.     bmi.bmHeader.bmHeight = bm.bmHeight
  249.     bmi.bmHeader.bmSize = 40                'Size, in bytes, of the header
  250.     bmi.bmHeader.bmPlanes = 1               'Number of planes (always one for this instance)
  251.     bmi.bmHeader.bmBitCount = 24            'Bits per pixel (always 24 for this instance)
  252.     bmi.bmHeader.bmCompression = 0          'Compression :standard/none or RLE
  253.     'Get the image data into our array
  254.     GetDIBits SrcPictureBox.hdc, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0), bmi, 0
  255. End Sub
  256.  
  257. 'Set an image's data from a one-dimensional array (stream)
  258. Public Sub SetImageDataStream(DstPictureBox As PictureBox, OriginalWidth As Long, OriginalHeight As Long, ImageData() As Byte)
  259.     Dim bm As Bitmap
  260.     'Get the picture box information
  261.     GetObject DstPictureBox.Image, Len(bm), bm
  262.     'Create a temporary header to pass to the StretchDIBits call
  263.     Dim bmi As BITMAPINFO
  264.     bmi.bmHeader.bmWidth = OriginalWidth
  265.     bmi.bmHeader.bmHeight = OriginalHeight
  266.     bmi.bmHeader.bmSize = 40                'Size, in bytes, of the header
  267.     bmi.bmHeader.bmPlanes = 1               'Number of planes (always one for this instance)
  268.     bmi.bmHeader.bmBitCount = 24            'Bits per pixel (always 24 for this instance)
  269.     bmi.bmHeader.bmCompression = 0          'Compression :standard/none or RLE
  270.     'Send the array to the picture box and draw it accordingly
  271.     StretchDIBits DstPictureBox.hdc, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, OriginalWidth, OriginalHeight, ImageData(0), bmi, 0, vbSrcCopy
  272.     'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
  273.     If DstPictureBox.AutoRedraw = True Then
  274.         DstPictureBox.Picture = DstPictureBox.Image
  275.         DstPictureBox.Refresh
  276.     End If
  277.     'Always good to manually halt for external processes after heavy API usage
  278.     DoEvents
  279. End Sub
  280.  
  281.