What is the fastest way to create the mask of picture?
Here's the code I wrote:
Code:
Public Function Mask(Color As Long) As Boolean
Dim i As Long
Dim j As Long
Mask=false
If bValidSprite Then
For i = 0 To lSpriteWidth - 1
For j = 0 To lSpriteHeight - 1
If GetPixel(DCSprite, i, j) = Color Then
Call SetPixel(DCMask, i, j, vbWhite)
Else
Call SetPixel(DCMask, i, j, vbBlack)
End If
Next j
Next i
bValidMask = True
Mask=true
End If
End Function
change the i and j longs to integers.
change 'next i' and 'next j' to only 'next'
and use setpixelv instead of setpixel...
if you are using a picturebox, use ScaleMode 3
Originally posted by cyborg
change the i and j longs to integers. slower
change 'next i' and 'next j' to only 'next' bad coding practice
and use setpixelv instead of setpixel... good
if you are using a picturebox, use ScaleMode 3 irrelevant
For best performance, use Get/SetDIBits.
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
(Just a heads-up)
I'm still not sure how to do the cleanup in this code, but I'm sure it would be deleting the bitmaps and BMPs, etc. Here are the declarations:
VB Code:
Public Const BI_RGB = 0&
Public Const DIB_RGB_COLORS = 0
Public Type mLong
L As Long
End Type
Public Type mRGB
R As Byte
G As Byte
B As Byte
A As Byte
End Type
Public 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
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Public Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As mRGB
End Type
Public Declare Function GetDIBits Lib "gdi32" (ByVal aHDC 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
Public Declare Function SetDIBits 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
Public Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long
Public Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Last edited by Sastraxi; Nov 16th, 2002 at 01:19 PM.
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
(Just a heads-up)
This is what the code does, step by step. First, it get's the hDC's bitmap pointer. Then, it takes this and, from it, gets the actual bitmap's info. After this, it fills in the values for a normal bitmap in the header, since from a DC this is one of the two things we don't get back (if you sent it a picture, you'd be able to get it all back, but we'd have to modify the code heavily). The other thing it doesn't get back is the actual bitmap data (sBMP/mBMP.bmBits), so we get this with GetDIBits. Now we have a one-dimensional array holding all of our bytes.
Now, you see all these Morph2D calls in there. They get the one-dimensional index from a two-dimensional one (one-dimensional arrays are faster so that's why they are used). And, GetDIBits returns the bitmap upside-down, so we always use Height - J to get the real Y value.
The LSet value puts any value into any other value (like putting a type with two bytes in it into an integer). In this case, we're assigning two long values to a 4-byte type, and since long is 4 bytes, it fills up the type nicely with the R, G, B data we want.
After this, we use SetDIBits to put the bits back to the DC from whence they came. I think that's it, but I haven't tested the code yet, so if there are any errors (and probably stupid ones), let me know.
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
(Just a heads-up)
Originally posted by cyborg if you're using a picturebox with scalemode = 3, use scalewidth and scaleheight instead of width and height...
ScaleWidth and ScaleHeight should be used regardless of the ScaleMode. No matter what mode you're in, if the border's still there, Width and Height are going to give you inproper values.
How many times did you try it? Did you try to switch the order of the two tests? Those who have most often got the result of the integer test using nearly twice the time of long.
But Sastraxi posted a better way to time the test. I used his code (I hope he doesn't mind me using it) to developed a test for both variable types. Try this.
Thanks, NoteMe, I don't mind at all, I love it when others use my code
So, long came up 7.3 s and integer was 9 s (with Winamp running). A second test, using integer first, came up with 7.7 for integer and 7.3 for long. So, in both tests, longs were faster And I'm about to make changes to some code, as it's wrong...
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
(Just a heads-up)
Originally posted by NoteMe How many times did you try it? Did you try to switch the order of the two tests? Those who have most often got the result of the integer test using nearly twice the time of long.
But Sastraxi posted a better way to time the test. I used his code (I hope he doesn't mind me using it) to developed a test for both variable types. Try this.
All the times I've tested it, the differences were always in milliseconds, not nearly twice as long.
I didn't know you where a comedian HOBO. But don't try to make any money on it. You wouldn't get rich. But seriously you should try the OTHER TEST.....
Originally posted by NoteMe I didn't know you where a comedian HOBO. But don't try to make any money on it. You wouldn't get rich. But seriously you should try the OTHER TEST.....
Dude. Seriously. I don't know what you're talkinga bout? What's 'the other test?' In that matter, what do you refer to as the 'old test?'
He posted a link to a thread, and then a few posts later made a post with an EXE. These were the two tests if I'm not mistaken... a simple miscommunication guys; NoteMe thought that you (Hobo) were talking about his first test in your post "all the times i've tested it....", and it all went downhill from there.
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
(Just a heads-up)
NoteMe: I wasn't trying to be an ass our anything. In the first post, yes I was joking around, but I didn't mean for it to be offensive or anything. I was interested in seeing what you meant.
long should be the faster datatype, according to MS, long is the 32 bit native datatype, so the compiler has less work to do, but if those tests say otherwise, i can't exactly argue.
It is true, and is even more noticable in the IDE (usually). On mine (my celeron has the worst fricken' FPU), they are very close. But it may have nothing to do with the FPU... it probably doesn't.... why am I posting th--
I just went cross-eyed...
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
(Just a heads-up)
Ok guys... Just stop discussing on longs and integers... The best method of improving performance is to improve algorithms, and not changing longs to bytes or boolean or whatever... Sure data alignment is important for fast data transfer. But if I have to do an array of colors, if I use bytes or longs is the same thing. I can read up to 4 bytes at time and put them on a long (I don't think vb can do this, but C sure can). If I really want to speed up things without optimizing algorithms I MUST program in assemby... Or at least in C... But windows programming in C isn't easy, a LOT of costants and a LOT of API calls... You just enter into Windows specifics... And it is so hard to make a simple "hello world" application from scratch (and without the template ), think about making a game!!! VB is the most productive programming language, you can do everything (almost) in a short time...
Sastraxi:
Thanks for code... At first look I can understand nothing... Maybe I'll get more in feel with it looking, and looking, and overlooking at it
Cyborg:
Thanks for SetPixelV, but I want accurate colors
The SetPixelV function sets the pixel at the specified coordinates to the closest approximation of the specified color. SetPixelV is faster than SetPixel because it does not need to return the color value of the point actually painted.
Maybe the approximation is not noticeable, I think it depends from the type of device you write to... About the speed, the difference with SetPixel is an assignment at the end of the "job"... In assembly means:
Code:
' Assuming that the eax register is modified,
'Maybe I can pop the color from the stack:
...
Pop eax
Ret
'Or if the eax register is not modified at all, simply:
...
Ret
These are a one cycle clock instructions (from Pentium I to ....), so I don't think the speed gain is noticeable... Maybe anyone has tested it ???
Tomorrow I'll do the test and post code (if anybody else do)...