|
-
Nov 2nd, 2002, 10:14 AM
#1
Thread Starter
Addicted Member
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.
-
Nov 2nd, 2002, 10:50 AM
#2
Ex-Super Mod'rater
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:
Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long
Private Declare Function VarPtr Lib "msvbvm50.dll" (Ptr As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Type SAFEARRAYBOUND
cElements As Long
lLbound As Long
End Type
Private Type SAFEARRAY2D
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
Bounds(0 To 1) As SAFEARRAYBOUND
End Type
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
'Code
Dim i As Integer
Dim j As Integer
Dim pic() As Byte
Dim sa As SAFEARRAY2D
Dim bmp As BITMAP
Dim r As Long, g As Long, b As Long
GetObjectAPI Picture1.Picture, Len(bmp), bmp
With sa
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = bmp.bmHeight
.Bounds(1).lLbound = 0
.Bounds(1).cElements = bmp.bmWidthBytes
.pvData = bmp.bmBits
End With
CopyMemory ByVal VarPtrArray(pic), VarPtr(sa), 4
For i = 0 To UBound(pic, 1) - 3 Step 3
For j = 0 To UBound(pic, 2)
r = pic(i + 2, j)
g = pic(i + 1, j)
b = pic(i, j)
pic(i, j) = 255 - b
pic(i + 1, j) = 255 - g
pic(i + 2, j) = 255 - r
Next
Next
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.

-
Nov 2nd, 2002, 11:06 AM
#3
Thread Starter
Addicted Member
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
-
Nov 2nd, 2002, 02:25 PM
#4
Ex-Super Mod'rater
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.

-
Nov 2nd, 2002, 04:31 PM
#5
Thread Starter
Addicted Member
can anyone second Electroman's opintion that a DC would be faster?
Thanks
- Jake
-
Nov 2nd, 2002, 06:48 PM
#6
Ex-Super Mod'rater
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.

-
Nov 2nd, 2002, 07:04 PM
#7
Thread Starter
Addicted Member
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:
' it comes in already having the bitmap file open for binary as #f
...
MsgBox ("Begin Color Table Fix")
' PROCEDURE:
' 1) Get the BGR value of the background color
' 2) Get the BGR value of the color currently in table position 0
' 3) Put the BGR value of the background color into table position 0
' 4) Put the BGR value of the old position 0 color into the position that the background color came from
' 5) Change the raster data for the bg pixels from old color table position of bg color to "00"
' and change the raster data for the pixels that referenced the old position 0 color to that color's new color table position
MsgBox ("1")
Dim OrigBGColor
'MsgBox (BOB_p1)
Get #f, BOB_p1, BOB_FstByteColTblRef
'MsgBox ("First Pixel Color Table Reference: " & BOB_FstByteColTblRef)
If BOB_FstByteColTblRef > 0 Then
' 1) Get the BGR value of the background color
Dim decColTblRef_1
Dim decColTblRef_2
Dim decColTblRef_3
Dim decColTblRef_4
Dim decColTblRef_5
Dim decColTblRef_6
Dim bgColBlVal As Byte
Dim bgColGrVal As Byte
Dim bgColRdVal As Byte
decColTblRef_1 = (BOB_FstByteColTblRef * 4)
decColTblRef_2 = (decColTblRef_1 + 55)
decColTblRef_4 = (decColTblRef_2) ' position in byte array of blue val of bg color
decColTblRef_5 = (decColTblRef_2 + 1) ' position in byte array of green val of bg color
decColTblRef_6 = (decColTblRef_2 + 2) ' position in byte array of red val of bg color
Get #f, decColTblRef_4, bgColBlVal
Get #f, decColTblRef_5, bgColGrVal
Get #f, decColTblRef_6, bgColRdVal
MsgBox ("2")
'MsgBox ("the background color of the bitmap is: " & vbNewLine & "Blue = " & bgColBlVal & " Green = " & bgColGrVal & " Red = " & bgColRdVal)
'MsgBox ("BL: " & bgColBlVal & " GR: " & bgColGrVal & " RD: " & bgColRdVal)
' 2) Get the BGR value of the color currently in table position 0
Dim OrigPos0Bl As Byte
Dim OrigPos0Gr As Byte
Dim OrigPos0Rd As Byte
Get #f, 55, OrigPos0Bl
Get #f, 56, OrigPos0Gr
Get #f, 57, OrigPos0Rd
'MsgBox ("Bl: " & OrigPos0Bl & " Gr: " & OrigPos0Gr & " Rd: " & OrigPos0Rd)
' 3) Put the BGR value of the background color into table position 0
Put #f, 55, bgColBlVal
Put #f, 56, bgColGrVal
Put #f, 57, bgColRdVal
' 4) Put the BGR value of the old position 0 color into the position that the background color came from
' put it in whatever position the bgcol came (BOB_FstByteColTblRef) from
Put #f, decColTblRef_4, OrigPos0Bl
Put #f, decColTblRef_5, OrigPos0Gr
Put #f, decColTblRef_6, OrigPos0Rd
MsgBox ("3")
' 5) Change the raster data for the bg pixels from old color table position of bg color to "00"
' the parse is: if byte = BOB_FstByteColTblRef Then put byte = "ff"
' and...Change the raster data for the pixels that referenced the old position 0 color to that color's new color table position
Dim tfParInt
Dim tfParInt_1
Dim rByteValHex_1 As Byte
Dim rByteValHex2 As Byte
Dim tfBGColRefTemp As Byte
tfBGColRefTemp = 255
Dim tfOthColRefTemp As Byte
tfOthColRefTemp = 254
'MsgBox (BOB_FstByteColTblRef)
'MsgBox (BOB_p1)
For tfParInt = BOB_p1 To lngFileLen
rByteValHex_1 = argArray_raster(tfParInt)
'MsgBox (rByteValHex_1)
If rByteValHex_1 = BOB_FstByteColTblRef Then
'MsgBox ("here 1")
Put #f, tfParInt, tfBGColRefTemp
End If
If rByteValHex_1 = 0 Then
'MsgBox ("here 2")
Put #f, tfParInt, tfOthColRefTemp
End If
Next tfParInt
MsgBox ("4")
On Error Resume Next
For tfParInt_1 = 1 To lngFileLen
Dim tfParser
tfParser = (BOB + tfParInt_1)
'MsgBox ("tfParser = (should be 347)" & tfParser)
Get #f, tfParser, rByteValHex2
'MsgBox ("here 3, rByteValHex2 = (should be 255)" & rByteValHex2)
If rByteValHex2 = 255 Then
' MsgBox ("reached here 4")
Put #f, tfParser, 0
Else
If rByteValHex2 = 254 Then
' MsgBox ("reached here 5")
Put #f, tfParser, BOB_FstByteColTblRef
End If
End If
Next tfParInt_1
MsgBox ("5")
Else
MsgBox ("The background color is already in the first color table position")
End If
MsgBox ("End Color Table Fix")
...
-
Nov 3rd, 2002, 05:21 AM
#8
Ex-Super Mod'rater
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.

-
Nov 3rd, 2002, 07:55 AM
#9
Ex-Super Mod'rater
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|