[RESOLVED] [VB6] - pointers and bitmaps
i have read several toturials and the autors don't explaint the very important thing:(
i understand that the pointers use BRG instead RGB. ok, but how can i compare the colors?
Code:
Option Explicit
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
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
Private Declare Function VarPtrArray Lib "msvbvm50.dll" Alias "VarPtr" (Ptr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Sub ChangeColor(Picture As StdPicture, OldColor As Long, NewColor As Long)
Dim pic() As Byte
Dim sa As SAFEARRAY2D
Dim bmp As BITMAP
Dim r As Long, g As Long, b As Long
Dim r2 As Long, g2 As Long, b2 As Long
Dim X As Long, Y As Long
GetObjectAPI 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 Y = 0 To UBound(pic, 2)
For X = 0 To UBound(pic, 1) Step 3
r = pic(X + 2, Y)
g = pic(X + 1, Y)
b = pic(X, Y)
If RGB(b, g, r) = OldColor Then
r2 = NewColor And 255
b2 = (NewColor And &HFF0000) \ 65536
g2 = (NewColor And 65535) \ 256
pic(X + 2, Y) = b2
pic(X + 1, Y) = g2
pic(X, Y) = r2
End If
Next X
Next Y
CopyMemory ByVal VarPtrArray(pic), 0&, 4
End Sub
Private Sub Command1_Click()
'TransparentAlphaBlend Picture1.Picture, Picture2.Picture, CByte(Text1.Text)
ChangeColor Picture1.Picture, Picture3.BackColor, Picture4.BackColor
Picture1.Refresh
End Sub
my problem is here:
Code:
For Y = 0 To UBound(pic, 2)
For X = 0 To UBound(pic, 1) Step 3
r = pic(X + 2, Y)
g = pic(X + 1, Y)
b = pic(X, Y)
If RGB(b, g, r) = OldColor Then
r2 = NewColor And 255
b2 = (NewColor And &HFF0000) \ 65536
g2 = (NewColor And 65535) \ 256
pic(X + 2, Y) = b2
pic(X + 1, Y) = g2
pic(X, Y) = r2
End If
Next X
Next Y
because that if isn't used... and i have sure that oldcolor realy exists:(
so can anyone advice me?
(i'm trying these, because i need more speed that DIB's)
Re: [VB6] - pointers and bitmaps
Your matter is not a very simple problem :D
I had the same question several years ago and I realized that there aren't easy way to compare two colors from their codes. The only solution I found (that's not easy at all) is to convert your color code into Cie L*a*b* code. Once you got this, you can proceed to calculate the distance between the two colors you want to compare.
Now I lost the source codes but if you look for in MasterDrive.it there's should still be the topic I opened about this. Enjoy ;)
:wave:
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
Cereal Killer
Your matter is not a very simple problem :D
I had the same question several years ago and I realized that there aren't easy way to compare two colors from their codes. The only solution I found (that's not easy at all) is to convert your color code into Cie L*a*b* code. Once you got this, you can proceed to calculate the distance between the two colors you want to compare.
Now I lost the source codes but if you look for in MasterDrive.it there's should still be the topic I opened about this. Enjoy ;)
:wave:
"there aren't easy way to compare two colors from their codes" then let us simplificate them hehehe
(like i did with my Graphics class(using DIB's) hehehe)
sorry what is 'MasterDrive'?
my big objective is avoid the flicker on Opacity effect(in controls)... then i need more speed than DIB's;)
http://www.cambalinho.blogspot.pt/
(my blog see it. i belive the graphics it's in 2DSprite control, if isn't just tell me;))
Re: [VB6] - pointers and bitmaps
To avoid flicker, you use a buffer to draw everything onto, then BitBlt the result to your visible surface.
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
WizBang
To avoid flicker, you use a buffer to draw everything onto, then BitBlt the result to your visible surface.
i try that, in usercontrols, without sucess and i see the code more slow:(
(even i did 1 change from DC to my class DIB's and seems more slow too:()
Re: [VB6] - pointers and bitmaps
Rather than copying the bitmap to a byte array, you can use CreateCompatibleDC to create a DC (device context), then SelectObject to give the picture the DC. Then you can access the pixels just like it was a PictureBox, so you can compare the colors simply.
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
WizBang
Rather than copying the bitmap to a byte array, you can use CreateCompatibleDC to create a DC (device context), then SelectObject to give the picture the DC. Then you can access the pixels just like it was a PictureBox, so you can compare the colors simply.
sorry not so simply:(
i did that before and takes very time to do my TransparentAlphaBlend()(have 2 'FOR''s):(
in these case, the changing color, was for help me use the pointers... nothing more
can you give me a very simple Double Buffering sample(just for draw, i don't need an animation)?
Re: [VB6] - pointers and bitmaps
If all you need is to make one color "transparent", thereby allowing a background color to show through, then a very fast method is one involving some BitBlt calls and a few other APIs. No looping through every pixel. It is therefore very very fast. You will find many examples of this on PlanetSourceCode.com, though do watch out for bad code examples. Such examples are especially prone to lacking proper disposal of objects created via API calls. All objects must be destroyed properly to avoid memory leaks.
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
WizBang
If all you need is to make one color "transparent", thereby allowing a background color to show through, then a very fast method is one involving some BitBlt calls and a few other APIs. No looping through every pixel. It is therefore very very fast. You will find many examples of this on PlanetSourceCode.com, though do watch out for bad code examples. Such examples are especially prone tolacking proper disposal of objects created via API calls. All objects must be destroyed properly to avoid memory leaks.
"All objects must be destroyed properly to avoid memory leaks. " these can slow down the things?
Re: [VB6] - pointers and bitmaps
Sure, as you run low on memory, things start caching to the hard drive, as objects that fit in AVAILABLE MEMORY are loaded back in. Until AVAILABLE MEMORY = 0%, then you have problems. Windows 7 can block things to an extent, but not XP.
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
Cambalinho
"All objects must be destroyed properly to avoid memory leaks. " these can slow down the things?
I don't suppose you'd necessarily notice a slowing down until physical memory gets low. But regardless, leaks are trouble, and easily avoidable with adherence to good coding practices.
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
dglienna
Sure, as you run low on memory, things start caching to the hard drive, as objects that fit in AVAILABLE MEMORY are loaded back in. Until AVAILABLE MEMORY = 0%, then you have problems. Windows 7 can block things to an extent, but not XP.
ok.. now i have another question-out off topic... sorrry:
how DIB's can slow down things?
(if anyone can't tell me, please tell me something for read)
Re: [VB6] - pointers and bitmaps
It not so much that DIBs can slow things down. But poorly written code can slow things down.
In any case, you don't need to use DIBs to do the transparency.
1 Attachment(s)
Re: [VB6] - pointers and bitmaps
Quote:
Originally Posted by
WizBang
It not so much that DIBs can slow things down. But poorly written code can slow things down.
In any case, you don't need to use DIBs to do the transparency.
i have these class(builded by me)...
what i need to know if i'm programming correctly with DIB's;)
i have my 2D Sprite control. if i put several of them in a form(just for draw an image), the form will take very time to show. please tell something
thanks for all
Re: [VB6] - pointers and bitmaps
OK, I've looked over your class file. Although unfamiliar with your particular programming style, I can see many things which could be improved. For instance, you have some Do...Loops, and within the loops there is an If Then Else. This is a case where you could use Do Until or Do While. Also, there is a set of If Then statements within the ChangeImage sub which all have one condition in common. So in this case you could nest these inside one If Then for that common condition rather than test it for each one separately.
Incidentally, you can draw directly onto the surface of the UserControl, so it if often unnecessary to use a separate PictureBox. Even so, passing it as an Object is slower than passing it as a PictureBox.
However, changing a color in an image pixel by pixel is always very slow compared to using the same technique as for transparency. That's what I'd recommend. Rotating an image is of course another matter, but that's not likely to be what's slowing down the loading of the form.