Can it be done? I want to get a Bitmap object (so I can do the bitmap array manipulations) but I need to get it with the DC that I have. How would this be done?
Printable View
Can it be done? I want to get a Bitmap object (so I can do the bitmap array manipulations) but I need to get it with the DC that I have. How would this be done?
use the GetCurrentObject API
Code:Private Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long
Private Const OBJ_BITMAP = 7
Private Function GetBmpHandle(hdc As Long)
GetBmpHandle = GetCurrentObject(hdc, OBJ_BITMAP)
End Function
Thanks! Do you know how to get a bitmap long into a bitmap type?
Well, yes :)
once you retreive the handle of the current bitmap object in your dc, just use the GetObject API to get your BITMAP type. Your code could now look like this :
Code:dim hBmp as long
dim myBmp as BITMAP
hBmp = GetCurrentObject(myHdc, OBJ_BITMAP)
GetObject hBmp, len(myBmp), myBmp
Wow. I need to learn more API, no? ;)
Cheers for all the help!
Just glad I could help... damn, I think I'm getting addicted to this forum :D Anyway, wanna know my API secret ? :) http://msdn.microsoft.com/library/de..._reference.asp If you are able to deal with learning from c++ examples, all your API questions will be answered there!
- Valkan
How come whenever I go to the MSDN now, it comes up with a stupid list?
Huh!?!... what list are you talking about?Quote:
Originally posted by Sastraxi
How come whenever I go to the MSDN now, it comes up with a stupid list?
After clicking your link (or any link on the MSDN for that matter), it comes up with a list that contains these links (no formatting, no text formatting, just a white page with these links):Weird, no?Code:Welcome to the MSDN Library
Welcome to the MSDN Library
Component Development
Data Access
Development (General)
Enterprise Development
Graphics and Multimedia
Messaging and Collaboration
Mobile and Embedded Development
.NET Development
.NET Development
Networking and Directory Services
Office Solutions Development
Security
Security
Setup and System Administration
User Interface Design and Development
User Interface Design and Development
Visual Tools and Languages
Web Development
Windows Development
XML Web Services
XML Web Services
MSDN Library Archive
Hmm.. It's not working... It's retrieving everything correctly, and I'd look to the MSDN for advice, but as I mentioned, it's not working for me >_<. Here's what my function looks like:I know there's still lots to be done but it would be functional, for now. But it isn't: the arrays are empty (0, 0 is index out of bounds). Do you, or the MSDN, have anything to say to this?VB Code:
Public Function AlphaBltFast(ByVal hDest As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrc As Long, ByVal hAlpha As Long, ByVal xSrc As Long, ByVal ySrc As Long) Dim I As Long Dim J As Long Dim TempR As Long Dim TempG As Long Dim TempB As Long Dim AlphaVal As Long Dim SrcVal As Long Dim DestVal As Long Dim dBitmap As Long Dim dBMP As BITMAP Dim dPic() As Byte Dim dSA As SAFEARRAY2D Dim sBitmap As Long Dim sBMP As BITMAP Dim sPic() As Byte Dim sSA As SAFEARRAY2D Dim aBitmap As Long Dim aBMP As BITMAP Dim aPic() As Byte Dim aSA As SAFEARRAY2D Dim nSrcX As Long Dim nSrcY As Long dBitmap = GetCurrentObject(hDest, OBJ_BITMAP) sBitmap = GetCurrentObject(hSrc, OBJ_BITMAP) aBitmap = GetCurrentObject(hAlpha, OBJ_BITMAP) GetObject dBitmap, Len(dBMP), dBMP GetObject sBitmap, Len(sBMP), sBMP GetObject aBitmap, Len(aBMP), aBMP dSA.cbElements = 1 dSA.cDims = 2 dSA.Bounds(0).lLbound = 0 dSA.Bounds(0).cElements = dBMP.bmHeight dSA.Bounds(1).lLbound = 0 dSA.Bounds(1).cElements = dBMP.bmWidthBytes dSA.pvData = dBMP.bmBits CopyMemory ByVal VarPtrArray(dPic), VarPtr(dSA), 4 sSA.cbElements = 1 sSA.cDims = 2 sSA.Bounds(0).lLbound = 0 sSA.Bounds(0).cElements = sBMP.bmHeight sSA.Bounds(1).lLbound = 0 sSA.Bounds(1).cElements = sBMP.bmWidthBytes sSA.pvData = sBMP.bmBits CopyMemory ByVal VarPtrArray(sPic), VarPtr(sSA), 4 aSA.cbElements = 1 aSA.cDims = 2 aSA.Bounds(0).lLbound = 0 aSA.Bounds(0).cElements = aBMP.bmHeight aSA.Bounds(1).lLbound = 0 aSA.Bounds(1).cElements = aBMP.bmWidthBytes aSA.pvData = aBMP.bmBits CopyMemory ByVal VarPtrArray(aPic), VarPtr(aSA), 4 For J = y To y + (nHeight - 1) For I = x * 3 To (x + nWidth) * 3 Step 3 'I - x + xSrc, J - y + ySrc nSrcX = ((I / 3) - x + xSrc) * 3 nSrcY = J - y + ySrc AlphaVal = aPic(nSrcX + 2, nSrcY) SrcVal = sPic(nSrcY + 2, nSrcY) DestVal = dPic(I + 2, J) TempR = (AlphaVal * CLng(SrcVal + 256 - DestVal)) / 256 + DestVal - AlphaVal AlphaVal = aPic(nSrcX + 1, nSrcY) SrcVal = sPic(nSrcY + 1, nSrcY) DestVal = dPic(I + 1, J) TempG = (AlphaVal * CLng(SrcVal + 256 - DestVal)) / 256 + DestVal - AlphaVal AlphaVal = aPic(nSrcX, nSrcY) SrcVal = sPic(nSrcY, nSrcY) DestVal = dPic(I, J) TempB = (AlphaVal * CLng(SrcVal + 256 - DestVal)) / 256 + DestVal - AlphaVal dPic(I + 2, J) = TempR dPic(I + 1, J) = TempG dPic(I, J) = TempB Next I Next J CopyMemory ByVal VarPtrArray(dPic), 0&, 4 CopyMemory ByVal VarPtrArray(sPic), 0&, 4 CopyMemory ByVal VarPtrArray(aPic), 0&, 4 End Function
Hum... ok, by reading your code i didn't see something wrong at first glance so i copied it (and btw... is there a way to copy correctly code posted on this board?) and try to use your function. And something very strange is happenig... after the getobject calls, every member for all the bitmap variable are set correctly... Every members exepted for the bmbits wich is always 0 so no pointer to the data!? Now, unless my computer is in worst shape than i tought and that does this only for me :rolleyes:, This would be why you get the out of bound error since copymemory will fail.
So now i'm speechless... i've seen exemple using this technique to change the pixels from a bitamp and even used it myselt with success. So why is it not working now... i really don't know (that's why i brought up the computer being in bad shape thing... i know i've already done this... but now it doesn't work!!! I just don't get it.)
so now i'm gonna go to sleep... i'll probably see things more clearly tomorow. If you get a chance, try to see what are the values for .bmbits when you run your code to see if you have the same problem.
Did I not mention that? D'oh. :) That's what problem I'm having, that the bmBits are 0, so that it doesn't work. I was thinking it had to do with the fact that the pictureboxes I'm getting the DCs from are autoredraw, but I'm not sure.
Well... if that is because of the autoredraw, I would be even more confuse... you see, i've tried almost any way I know of putting a darn bitmap in a dc (by using loadimage for the bitmap and then selecting it in a dc, in a memory dc, creating a bimap with createcompatiblebitmap. I've tried using picutre.image in getobject etc... ) but always to the same result, bmbits is set to 0 all the f'n (sorry it slipped :D ) time.Quote:
Originally posted by Sastraxi
Did I not mention that? D'oh. :) That's what problem I'm having, that the bmBits are 0, so that it doesn't work. I was thinking it had to do with the fact that the pictureboxes I'm getting the DCs from are autoredraw, but I'm not sure.
Man! this is suppose to work... I guess we will need help from others to for this one.
I have to go to work soon, but i'll try to work something again when i come back.
- Valkan
Just posted this problem in the API forum... perhaps someone will be able to help with the getobject problem. Because as i've said before, i'm pretty sure the rest of your code is good.
BTW, good luck with the alphablend, i've tried implementing it once... was pretty cool, but awfully slow with big pictures. If you manage to do it fast, please send me the code
- Valkan
I've found out to get the pointer to bits in the BITMAP variable set to something else than 0. if you use picturebox.picture in the getobject call, it will work. But i still don't know why it doesn't work with a bitmap object thought...
Well, i'm the one who talked about the msdn being a great source for api info... and I didn't even when to check to description for the getobject function. Here is what i've found out:
this would also clarify for me the diference between the .picture and .image of a picturebox... .picture seems to be a dib (since it works with getobject) and .image is a ddb.Quote:
If hgdiobj is a handle to a bitmap created by calling CreateDIBSection, and the specified buffer is large enough, the GetObject function returns a DIBSECTION structure. In addition, the bmBits member of the BITMAP structure contained within the DIBSECTION will contain a pointer to the bitmap's bit values.
If hgdiobj is a handle to a bitmap created by any other means, GetObject returns only the width, height, and color format information of the bitmap. You can obtain the bitmap's bit values by calling the GetDIBits or GetBitmapBits function.
- Valkan
Excellent, my friend. Excellent, excellent, excellent, excellent. I'm really glad you've helped me with all this!
PS. The Get/SetPixel only takes 0.003 seconds, on average, to do a 16x16 alphablend. It takes a bit longer for a 20x25 (0.01 s) but it's pretty sufficient for what I'm using it for. I just wanted to be able to do it just this bit faster, hehe ;)
I'm just about to try it, BTW. :D Just had to get out my enthusiasm, as it's been a long, boring, painful day of tests at school :/
We have a winner....
GetDIBits is awesome. This works completely, 100% now. Excellent, man, excellent!VB Code:
Public Function Morph2D(X As Long, Y As Long, NumRow As Long) As Long Morph2D = (Y - 1) * NumRow + X End Function Public Function AlphaBltFast(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 hAlphaDC As Long, ByVal xSrc As Long, ByVal ySrc As Long) Dim I As Long Dim J As Long Dim TempR As Long Dim TempG As Long Dim TempB As Long Dim AlphaVal As mRGB Dim SrcVal As mRGB Dim DestVal As mRGB Dim dBitmap As Long Dim dBMP As BITMAP Dim dPic() As mRGB Dim dMem As BITMAPINFO Dim sBitmap As Long Dim sBMP As BITMAP Dim sPic() As mRGB Dim sMem As BITMAPINFO Dim aBitmap As Long Dim aBMP As BITMAP Dim aPic() As mRGB Dim aMem As BITMAPINFO dBitmap = GetCurrentObject(hDestDC, OBJ_BITMAP) sBitmap = GetCurrentObject(hSrcDC, OBJ_BITMAP) aBitmap = GetCurrentObject(hAlphaDC, OBJ_BITMAP) GetObjectAPI dBitmap, Len(dBMP), dBMP GetObjectAPI sBitmap, Len(sBMP), sBMP GetObjectAPI aBitmap, Len(aBMP), aBMP With dMem.bmiHeader .biBitCount = 32 .biCompression = BI_RGB .biPlanes = 1 .biSize = Len(dMem.bmiHeader) .biWidth = dBMP.bmWidth .biHeight = dBMP.bmHeight ReDim Preserve dPic(0 To (.biWidth * .biHeight) - 1) As mRGB End With GetDIBits hDestDC, dBitmap, 0, dBMP.bmHeight, dPic(0), dMem, DIB_RGB_COLORS With sMem.bmiHeader .biBitCount = 32 .biCompression = BI_RGB .biPlanes = 1 .biSize = Len(sMem.bmiHeader) .biWidth = sBMP.bmWidth .biHeight = sBMP.bmHeight ReDim Preserve sPic(0 To (.biWidth * .biHeight) - 1) As mRGB End With GetDIBits hSrcDC, sBitmap, 0, sBMP.bmHeight, sPic(0), sMem, DIB_RGB_COLORS With aMem.bmiHeader .biBitCount = 32 .biCompression = BI_RGB .biPlanes = 1 .biSize = Len(aMem.bmiHeader) .biWidth = aBMP.bmWidth .biHeight = aBMP.bmHeight ReDim Preserve aPic(0 To (.biWidth * .biHeight) - 1) As mRGB End With GetDIBits hAlphaDC, aBitmap, 0, aBMP.bmHeight, aPic(0), aMem, DIB_RGB_COLORS For J = Y To Y + (nHeight - 1) For I = X To X + (nWidth - 1) DestVal = dPic(Morph2D(I, dBMP.bmHeight - J, dBMP.bmWidth)) 'dColour.L = GetPixel(hDestDC, I, J) SrcVal = sPic(Morph2D(I - X + xSrc, sBMP.bmHeight - (J - Y + ySrc), sBMP.bmWidth)) 'sColour.L = GetPixel(hSrcDC, I - x + xSrc, J - y + ySrc) AlphaVal = aPic(Morph2D(I - X + xSrc, aBMP.bmHeight - (J - Y + ySrc), aBMP.bmWidth)) 'aColour.L = GetPixel(hAlphaDC, I - x + xSrc, J - y + ySrc) AlphaVal.R = 255 - AlphaVal.R AlphaVal.G = 255 - AlphaVal.G AlphaVal.B = 255 - AlphaVal.B TempR = (AlphaVal.R * CLng(SrcVal.R + 256 - DestVal.R)) / 256 + DestVal.R - AlphaVal.R TempG = (AlphaVal.G * CLng(SrcVal.G + 256 - DestVal.G)) / 256 + DestVal.G - AlphaVal.G TempB = (AlphaVal.B * CLng(SrcVal.B + 256 - DestVal.B)) / 256 + DestVal.B - AlphaVal.B With dPic(Morph2D(I, dBMP.bmHeight - J, dBMP.bmWidth)) .R = TempR .G = TempG .B = TempB End With Next I Next J SetDIBits hDestDC, dBitmap, 0, dBMP.bmHeight, dPic(0), dMem, DIB_RGB_COLORS End Function
Great man! I'm happy to see you have succeded. Beside it was a pleasure helping you... heck, it made me learn new stuff too :). stuff like the GDI can be a real pain in the ... sometime :( But hey, this was fun! Finally, I have a better understand of how to use the copy memory trick.:D
- Valkan
I think I have a complete understanding of it, you can get memory out in any format, which is both the beauty and the failing of it ;)
It's still pretty slow though.... but it's faster for larger images. I'm going to compile it to see how fast it goes.
[EDIT] Good news ;) Instead of 0.17s (IDE), it runs at 0.08s (compiled). More than two-times speed increase, which is nice.
Sastraxi, I would like to see your subs in action. I've been programming vb for about 4 years. I made my own very easy to use blit subs. I still don't know what an hDC is, and Bitblt looks like a heap of technical gibberish (I realize that it copies data extremely rapidly). Mostly it's the hDC and 7 other parameters that go with it that make it look more like "loose wires" than a "control panel". That's why I say I would like to see you post an example of your subs in action.
Do you mind running compiled code? The reason I'm hesitant to post the actual code is that I've used some pretty bad coding practices to get this test done...
If you don't trust me, I'll post it, but I hope you do :)
And here's a screenshot ;) Office, Apache, and EAC icons probably won't show up, I have their paths hard-coded. And if you don't have Winamp, it won't show up either. But IE should...
I got an error message: "failed to delete C:\" What does that mean? :pQuote:
Originally posted by Sastraxi
Do you mind running compiled code? The reason I'm hesitant to post the actual code is that I've used some pretty bad coding practices to get this test done...
If you don't trust me, I'll post it, but I hope you do :)
That's pretty cool, though. What are you planning to do with it/use it for?
intresting.. at first click I got .11s, and second and later i was getting .06 and even .00 (1ghz duron). I got "subscript out of" after clicking about 20 times.
'Then don't click 20 times."
Dafi: I got the same error message after clicking about 50 times.
The first result was 11, and after that it used 1,2,3 (Athlon 1,9+)...I have WinAmp, but it didn't show. But IE did).
took 0.02 for me..
i would like to have the code.....can you attach it please :)
Okay, but let me clean it up first. There's definately some stuff that's draining the memory like crazy, I'll do a test.
[EDIT]I've found the problem, which lies in the SmoothIconBlt function. I think it's the memory DCs I'm creating, let me check it and I'll post![/EDIT]
And I'll put in a little special effect for you guys, enumerating the real quicklaunch icons and sticking the first 5 in ;)
Okay, DON'T run this program anymore, lol. It has a huge memory leak that eventually destroys all of your memory... lol. Anyway, you might notice that the subscript out of range is in a horrible, Win16-emulation bold font. That shows real trouble, so, like I said, don't use it until I figure out what's wrong with it ;)
This was very tricky to find: in win98 that I use, when you double-click to start a file, a mouseup event occurs. It was causing an error in one of my projects.
Here's the code, tell me if you're able to fix the memory leaks...
thanks alot! that will be really useful for me! :)
Yeah, use it an any way you please :) I just hope you tell me about anything you use it in ;)
Okay, found out how to fix the Memory Leak in SmoothIconBlt.
New/Changed Code:VB Code:
Public Function DestroyDC(ByVal DC As Long, ByVal hOldBitmap As Long) As Long DeleteObject SelectObject(DC, hOldBitmap) ReleaseDC GetDesktopWindow, DC DeleteDC DC End Function Public Function CreateMyDC(WidthInPixels As Long, HeightInPixels As Long, ByRef hOldBitmap As Long, Optional CompatibleDC As Long) As Long '## NOTE THIS FUNCTION IS FROM SOMEONE ON VBW. I CAN'T REMEMBER THEIR NAME SO IF YOU DO, PLEASE '## TELL ME SO APPROPRIATE THANKS CAN BE GIVEN Dim hCompatibleDC As Long Dim hMemDC As Long 'check there is a compatible DC If CompatibleDC = 0 Then hCompatibleDC = GetDC(GetDesktopWindow) Else hCompatibleDC = CompatibleDC End If 'CreateDC hMemDC = CreateCompatibleDC(hCompatibleDC) 'Get Default Bitmap Out of DC and Delete it and Put New one in. hOldBitmap = SelectObject(hMemDC, CreateCompatibleBitmap(hCompatibleDC, WidthInPixels, HeightInPixels)) 'and We're Done CreateMyDC = hMemDC End Function Public Function SmoothIconBlt(ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal hExeSrc As String, ByVal hIndex As Long, ByVal hSmallIcon As Boolean, Optional SmoothValue As Long = smoothval) As Long Dim hSmIco As Long Dim hLgIco As Long Dim hResult As Long Dim hImgDC As Long Dim hMaskDC As Long Dim hTempDC As Long Dim hImgOld As Long Dim hMaskOld As Long Dim hTempOld As Long hImgDC = CreateMyDC(16, 16, hImgOld) hMaskDC = CreateMyDC(16, 16, hMaskOld) hTempDC = CreateMyDC(16, 16, hTempOld) Call ExtractIconEx(hExeSrc, hIndex, hLgIco, hSmIco, 1) If hSmallIcon Then hResult = DrawIconEx(hMaskDC, 0, 0, hSmIco, 16, 16, 0, 0, DI_MASK) hResult = DrawIconEx(hImgDC, 0, 0, hSmIco, 16, 16, 0, 0, DI_IMAGE) SmoothMaskFast hTempDC, hMaskDC, 0, 0, 16, 16, SmoothValue AlphaBltFast hDestDC, X, Y, 16, 16, hImgDC, hMaskDC, 0, 0 Else hResult = DrawIconEx(hMaskDC, 0, 0, hLgIco, 32, 32, 0, 0, DI_MASK) hResult = DrawIconEx(hImgDC, 0, 0, hLgIco, 32, 32, 0, 0, DI_IMAGE) SmoothMaskFast hTempDC, hMaskDC, 0, 0, 32, 32, SmoothValue * 4 AlphaBltFast hDestDC, X, Y, 32, 32, hImgDC, hMaskDC, 0, 0 End If DestroyIcon hSmIco: DestroyIcon hLgIco DestroyDC hImgDC, hImgOld DestroyDC hMaskDC, hMaskOld DestroyDC hTempDC, hTempOld End Function
there gotta be some leaks left, cuz my comp gets really slow after using that program for a while, and i've got the error "cant create autoredraw image" or whatever it says...
Index Out of Bounds for SmoothMaskFast, is that your error? Yeah, I'm working on it, it doesn't seem to be fixed [yet]. There is also a MASSIVE memory leak in the TextBlt function (which is called by the CropTextBlt function, so both of them have leaks). If you can fix these, it'd be great.
no, the error message i got was "cant create autoredraw image"...
sorry, but im not so goot at there stuff so im not sure that i can be to any help... :(
but if i find anything, i'll let you know!
What function did you get the error in?