Results 1 to 9 of 9

Thread: fastest byte array of a bitmap ?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Location
    california
    Posts
    245

    fastest byte array of a bitmap ?

    Hello,

    I've written a small program that gets a bitmap into an array, does some if-then routienes on the raster data, then puts the array back to the bitmap file.

    But it is very slow.

    Would it be faster if I used a picture box and DIB functions (a DC etc.)?

    Thanks for any help

    - Jake
    Last edited by sequoyan; Nov 2nd, 2002 at 10:31 AM.

  2. #2
    Ex-Super Mod'rater Electroman's Avatar
    Join Date
    Sep 2000
    Location
    Newcastle, England
    Posts
    4,349
    This should help you if you do decide to use a picture box or if you decide to use a DC instead of the picture box see this thread http://www.vbforums.com/showthread.p...hreadid=210500 which sequoyan will already know of. This example inverts each pixel.
    VB Code:
    1. Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long
    2. Private Declare Function VarPtr Lib "msvbvm50.dll" (Ptr As Any) As Long
    3. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    4. Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
    5.  
    6. Private Type SAFEARRAYBOUND
    7.     cElements As Long
    8.     lLbound As Long
    9. End Type
    10.  
    11. Private Type SAFEARRAY2D
    12.     cDims As Integer
    13.     fFeatures As Integer
    14.     cbElements As Long
    15.     cLocks As Long
    16.     pvData As Long
    17.     Bounds(0 To 1) As SAFEARRAYBOUND
    18. End Type
    19.  
    20. Private Type BITMAP
    21.     bmType As Long
    22.     bmWidth As Long
    23.     bmHeight As Long
    24.     bmWidthBytes As Long
    25.     bmPlanes As Integer
    26.     bmBitsPixel As Integer
    27.     bmBits As Long
    28. End Type
    29.  
    30.  
    31. 'Code
    32. Dim i As Integer
    33. Dim j As Integer
    34. Dim pic() As Byte
    35. Dim sa As SAFEARRAY2D
    36. Dim bmp As BITMAP
    37. Dim r As Long, g As Long, b As Long
    38.  
    39. GetObjectAPI Picture1.Picture, Len(bmp), bmp
    40.  
    41. With sa
    42.     .cbElements = 1
    43.     .cDims = 2
    44.     .Bounds(0).lLbound = 0
    45.     .Bounds(0).cElements = bmp.bmHeight
    46.     .Bounds(1).lLbound = 0
    47.     .Bounds(1).cElements = bmp.bmWidthBytes
    48.     .pvData = bmp.bmBits
    49. End With
    50.  
    51. CopyMemory ByVal VarPtrArray(pic), VarPtr(sa), 4
    52.  
    53. For i = 0 To UBound(pic, 1) - 3 Step 3
    54.     For j = 0 To UBound(pic, 2)
    55.         r = pic(i + 2, j)
    56.         g = pic(i + 1, j)
    57.         b = pic(i, j)
    58.         pic(i, j) = 255 - b
    59.         pic(i + 1, j) = 255 - g
    60.         pic(i + 2, j) = 255 - r
    61.     Next
    62. Next
    63.  
    64. CopyMemory ByVal VarPtrArray(pic), 0&, 4
    Last edited by Electroman; Nov 2nd, 2002 at 03:02 PM.
    When your thread has been resolved please edit the original post in the thread ()
    and amend "-[RESOLVED]-" to the end of the title and change the icon to , Thank you.

    When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Location
    california
    Posts
    245
    Thanks for the code Electroman.

    What do you think is the fastest? The simple "Get" byte array that I'm currently using, a DC, or a picture box?

    Thanks for any advice

    - Sequoyan

  4. #4
    Ex-Super Mod'rater Electroman's Avatar
    Join Date
    Sep 2000
    Location
    Newcastle, England
    Posts
    4,349
    Personaly I would choose the DC because its the fastest way to edit an image Pixel by pixel but I aint sure about the speed of the "Get" byte array.

    I should point out the code I gave is for 24bit Bitmaps only and it would need some slight changes for other bpp's. and I think were the -3 is I think it should be -1 but i'm busy trying to fix that anyway.
    When your thread has been resolved please edit the original post in the thread ()
    and amend "-[RESOLVED]-" to the end of the title and change the icon to , Thank you.

    When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Location
    california
    Posts
    245
    can anyone second Electroman's opintion that a DC would be faster?

    Thanks

    - Jake

  6. #6
    Ex-Super Mod'rater Electroman's Avatar
    Join Date
    Sep 2000
    Location
    Newcastle, England
    Posts
    4,349
    Check out this example that I made, http://www.Electroman.co.uk/VBExampl...xelEditing.zip, it compares using GetPixel and SetPixelV to my method.
    When your thread has been resolved please edit the original post in the thread ()
    and amend "-[RESOLVED]-" to the end of the title and change the icon to , Thank you.

    When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Oct 2002
    Location
    california
    Posts
    245
    That's really cool. Thanks for the sample.

    Just for the hell of it I'm posting the section of code that is giving me a headache. It's part of a larger sub but I know that it is this part that is running really slow. Any help in optomizing it would be greatly appreciated.

    The procedure is at the beginning of the code.

    Thanks

    - Jake

    Here's the code that I would like to run faster:

    VB Code:
    1. ' it comes in already having the bitmap file open for binary as #f
    2. ...
    3.  
    4. MsgBox ("Begin Color Table Fix")
    5.  
    6.     ' PROCEDURE:
    7.     ' 1) Get the BGR value of the background color
    8.     ' 2) Get the BGR value of the color currently in table position 0
    9.     ' 3) Put the BGR value of the background color into table position 0
    10.     ' 4) Put the BGR value of the old position 0 color into the position that the background color came from
    11.     ' 5) Change the raster data for the bg pixels from old color table position of bg color to "00"
    12.     '    and change the raster data for the pixels that referenced the old position 0 color to that color's new color table position
    13.    
    14. MsgBox ("1")
    15. Dim OrigBGColor
    16. 'MsgBox (BOB_p1)
    17. Get #f, BOB_p1, BOB_FstByteColTblRef
    18. 'MsgBox ("First Pixel Color Table Reference: " & BOB_FstByteColTblRef)
    19.  
    20. If BOB_FstByteColTblRef > 0 Then
    21.  
    22.     ' 1) Get the BGR value of the background color
    23.     Dim decColTblRef_1
    24.     Dim decColTblRef_2
    25.     Dim decColTblRef_3
    26.     Dim decColTblRef_4
    27.     Dim decColTblRef_5
    28.     Dim decColTblRef_6
    29.  
    30.     Dim bgColBlVal As Byte
    31.     Dim bgColGrVal As Byte
    32.     Dim bgColRdVal As Byte
    33.    
    34.     decColTblRef_1 = (BOB_FstByteColTblRef * 4)
    35.     decColTblRef_2 = (decColTblRef_1 + 55)
    36.    
    37.     decColTblRef_4 = (decColTblRef_2)       ' position in byte array of blue val of bg color
    38.     decColTblRef_5 = (decColTblRef_2 + 1)   ' position in byte array of green val of bg color
    39.     decColTblRef_6 = (decColTblRef_2 + 2)   ' position in byte array of red val of bg color
    40.  
    41.     Get #f, decColTblRef_4, bgColBlVal
    42.     Get #f, decColTblRef_5, bgColGrVal
    43.     Get #f, decColTblRef_6, bgColRdVal
    44. MsgBox ("2")
    45.     'MsgBox ("the background color of the bitmap is: " & vbNewLine & "Blue = " & bgColBlVal & " Green = " & bgColGrVal & " Red = " & bgColRdVal)
    46.  
    47.     'MsgBox ("BL: " & bgColBlVal & " GR: " & bgColGrVal & " RD: " & bgColRdVal)
    48.    
    49.     ' 2) Get the BGR value of the color currently in table position 0
    50.     Dim OrigPos0Bl As Byte
    51.     Dim OrigPos0Gr As Byte
    52.     Dim OrigPos0Rd As Byte
    53.    
    54.     Get #f, 55, OrigPos0Bl
    55.     Get #f, 56, OrigPos0Gr
    56.     Get #f, 57, OrigPos0Rd
    57.    
    58.     'MsgBox ("Bl: " & OrigPos0Bl & " Gr: " & OrigPos0Gr & " Rd: " & OrigPos0Rd)
    59.    
    60.     ' 3) Put the BGR value of the background color into table position 0
    61.     Put #f, 55, bgColBlVal
    62.     Put #f, 56, bgColGrVal
    63.     Put #f, 57, bgColRdVal
    64.        
    65.     ' 4) Put the BGR value of the old position 0 color into the position that the background color came from
    66.     ' put it in whatever position the bgcol came (BOB_FstByteColTblRef) from
    67.    
    68.     Put #f, decColTblRef_4, OrigPos0Bl
    69.     Put #f, decColTblRef_5, OrigPos0Gr
    70.     Put #f, decColTblRef_6, OrigPos0Rd
    71. MsgBox ("3")
    72.     ' 5) Change the raster data for the bg pixels from old color table position of bg color to "00"
    73.     ' the parse is: if byte = BOB_FstByteColTblRef Then put byte = "ff"
    74.     ' and...Change the raster data for the pixels that referenced the old position 0 color to that color's new color table position
    75.            
    76.         Dim tfParInt
    77.         Dim tfParInt_1
    78.         Dim rByteValHex_1 As Byte
    79.         Dim rByteValHex2 As Byte
    80.         Dim tfBGColRefTemp As Byte
    81.         tfBGColRefTemp = 255
    82.         Dim tfOthColRefTemp As Byte
    83.         tfOthColRefTemp = 254
    84.         'MsgBox (BOB_FstByteColTblRef)
    85.         'MsgBox (BOB_p1)
    86.         For tfParInt = BOB_p1 To lngFileLen
    87.             rByteValHex_1 = argArray_raster(tfParInt)
    88.             'MsgBox (rByteValHex_1)
    89.             If rByteValHex_1 = BOB_FstByteColTblRef Then
    90.                 'MsgBox ("here 1")
    91.                 Put #f, tfParInt, tfBGColRefTemp
    92.             End If
    93.        
    94.             If rByteValHex_1 = 0 Then
    95.                 'MsgBox ("here 2")
    96.                 Put #f, tfParInt, tfOthColRefTemp
    97.             End If
    98.         Next tfParInt
    99. MsgBox ("4")
    100.         On Error Resume Next
    101.        
    102.         For tfParInt_1 = 1 To lngFileLen
    103.             Dim tfParser
    104.             tfParser = (BOB + tfParInt_1)
    105.             'MsgBox ("tfParser = (should be 347)" & tfParser)
    106.             Get #f, tfParser, rByteValHex2
    107.            
    108.             'MsgBox ("here  3, rByteValHex2 = (should be 255)" & rByteValHex2)
    109.             If rByteValHex2 = 255 Then
    110.            '     MsgBox ("reached here 4")
    111.                 Put #f, tfParser, 0
    112.             Else
    113.                 If rByteValHex2 = 254 Then
    114.            '         MsgBox ("reached here 5")
    115.                     Put #f, tfParser, BOB_FstByteColTblRef
    116.                 End If
    117.             End If
    118.         Next tfParInt_1
    119. MsgBox ("5")
    120. Else
    121.     MsgBox ("The background color is already in the first color table position")
    122. End If
    123.  
    124.  
    125. MsgBox ("End Color Table Fix")
    126.  
    127. ...

  8. #8
    Ex-Super Mod'rater Electroman's Avatar
    Join Date
    Sep 2000
    Location
    Newcastle, England
    Posts
    4,349
    I'll have a look and I see what I can do.
    When your thread has been resolved please edit the original post in the thread ()
    and amend "-[RESOLVED]-" to the end of the title and change the icon to , Thank you.

    When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

  9. #9
    Ex-Super Mod'rater Electroman's Avatar
    Join Date
    Sep 2000
    Location
    Newcastle, England
    Posts
    4,349
    My first thoughts would be to change the variables to arrays because arrays can be accessed alot faster. Also you've declared alot of variables without a type, I belive they're meant to be bytes so declaring them as types would take up 16 times less memory(Varient is 128Bit I belive and Byte is 8bit).
    Sorry but thats all I can think of coz the rest of your code is just the accessing of the file I don't know of another way of to do that quicker. My only idea on that is: is there a way to load the whole file in one go into a byte array then you could very simply edit the byte array and wouldn't need most of the variables your currently using, not to mention i'm sure its a lot faster to access files all in one go rather than reading little bits and writing little bits.

    Check out this Article which explains how to make sure your programs are as efficient as possible:
    http://216.26.168.92/vbsquare/misc/efficient/index.html

    Hope this helps.
    When your thread has been resolved please edit the original post in the thread ()
    and amend "-[RESOLVED]-" to the end of the title and change the icon to , Thank you.

    When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width