-
Oct 10th, 2024, 10:13 PM
#1
Thread Starter
Lively Member
-
Oct 11th, 2024, 02:29 AM
#2
Re: BitBlt from png with transparency
theres multiple ways.
it all depends on the needs.
easy and little code u have:
- DrawIconEx/CreateIconFromResourceEx that can load a PNG and render it, very little code.
- u have WIA that is quite easy to use. do a forum search for it.
a bit more involved u have
- GDI+ that can both load and render. no need for any DC to store the image, as it has its own container.
- GDI32 (together with GDI+ to load), so its basically two steps. one to load and one to store and render.
and more involved:
- Direct2d/WIC to load and render.
so everything u can find in vbforums. theres multiple threads about any of the methods.
just do a search and u will find plenty.
since your question was GDI32 u will need to first LOAD, and that require GDI+ or WIC or another solution.
and its important u load it and convert it into 32bit and after that u convert it into a gdi bitmap (dc) and use GdiAlphaBlend to render.
theres plenty of threads for GDI32 and how to load a PNG with transparency
-
Oct 11th, 2024, 04:26 AM
#3
Re: BitBlt from png with transparency
Since it wasn't mentioned above - here's what it looks like, when using the RC6-CairoWrapper:
Code:
Private Declare Function GdiAlphaBlend& Lib "gdi32" (ByVal hDC&, ByVal x&, ByVal y&, ByVal dx&, ByVal dy&, ByVal hdcSrc&, ByVal srcx&, ByVal srcy&, ByVal SrcdX&, ByVal SrcdY&, ByVal lBlendFunction&)
Private Sub Form_Load()
Cairo.ImageList.AddImage "MyPngKey1", "c:\temp\test.png" 'load and buffer the resource
Caption = "Click Me"
End Sub
Private Sub Form_Click()
AlphaRenderFromResourceTo Me.hDC, 10, 10, "MyPngKey1"
End Sub
Sub AlphaRenderFromResourceTo(ByVal hDC As Long, x, y, ImgKey As String)
Dim Src As cCairoSurface: Set Src = Cairo.ImageList(ImgKey)
With Cairo.CreateWin32Surface(Src.Width, Src.Height)
.CreateContext.RenderSurfaceContent Src, 0, 0
GdiAlphaBlend hDC, x, y, .Width, .Height, .GetDC, 0, 0, .Width, .Height, 2 ^ 24 + &HFF0000
End With
End Sub
Olaf
-
Oct 11th, 2024, 05:14 PM
#4
Thread Starter
Lively Member
Re: BitBlt from png with transparency
Originally Posted by baka
easy and little code u have:
- DrawIconEx/CreateIconFromResourceEx that can load a PNG and render it, very little code.
How would I do this? As far as I can tell it is only for icon resources?
No, Shaggy Hiker, I am not stealing your signature.
-
Oct 11th, 2024, 05:40 PM
#5
Re: BitBlt from png with transparency
if u do a search u find the answer
u can use CreateIconFromResourceEx to take a bytearray
hIcon = CreateIconFromResourceEx(bytes(0), UBound(bytes) + 1, 1, &H30000, width, height, 0)
so basically u load a png into a byte array and create a hicon that way
the same u can do from resource as well
after that just place it
DrawIconEx Me.Hdc, 0, 0, hIcon, width, height, 0, 0, 3
-
Oct 11th, 2024, 11:00 PM
#6
Thread Starter
Lively Member
Re: BitBlt from png with transparency
Hello baka. I cannot get it to work. CreateIconFromResourceEx just returns 0. GetLastError also returns 0.
I think my problem is similiar to this thread? https://www.vbforums.com/showthread....Ex-not-working
Here I have posted my code:
VB Code:
'Form path to read from
sPath = App.Path & "\textures\grid.png"
'Get data into array
nFile = FreeFile
Open sPath For Binary Access Read As #nFile
If LOF(nFile) > 0 Then
ReDim PNG(0 To LOF(nFile) - 1)
Get nFile, , PNG
Else
Close #nFile
Kill sPath
MsgBox "Texture grid.png missing or empty.", vbOKOnly, "Texture Missing"
Exit Sub
End If
Close #nFile
'Create icon
'hGridIcon always 0
hGridIcon = CreateIconFromResourceEx(PNG(0), UBound(PNG) + 1, 1, &H30000, 16, 16, 0)
No, Shaggy Hiker, I am not stealing your signature.
-
Oct 12th, 2024, 02:59 AM
#7
Re: BitBlt from png with transparency
need to use the correct API declaration.
and of course u need to use autoredraw=true
Code:
Private Declare Function CreateIconFromResourceEx Lib "user32" (ByRef presbits As Byte, ByVal dwResSize As Long, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
Private Declare Function DrawIconEx Lib "user32" (ByVal Hdc As Long, ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long
Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long
Private Sub Form_Load()
Dim Data() As Byte
Dim hIcon As Long
Dim Width As Long
Dim Height As Long
Open "C:\pictures\picture.png" For Binary As #1
ReDim Data(1 To LOF(1))
Get #1, , Data
Close #1
' Get Dimension from PNG-Header (Assuming its a correct PNG
Width = Data(17) * 16777216 + Data(18) * 65536 + Data(19) * 256 + Data(20)
Height = Data(21) * 16777216 + Data(22) * 65536 + Data(23) * 256 + Data(24)
Me.AutoRedraw = True
hIcon = CreateIconFromResourceEx(Data(1), UBound(Data), 1, &H30000, Width, Height, 0)
DrawIconEx Me.Hdc, 0, 0, hIcon, Width, Height, 0, 0, 3
DestroyIcon hIcon
End Sub
Last edited by baka; Oct 12th, 2024 at 06:39 AM.
-
Oct 12th, 2024, 11:37 AM
#8
Thread Starter
Lively Member
Re: BitBlt from png with transparency
Hello baka, I put your code in a new form and it does not work. (hIcon still 0)
I have seen some sites mention that support for PNGs in CreateIconFromResourceEx was added in Vista. Will it not work with previous versions?
Edit: Just tried on Windows 7 and still did not work.
Last edited by OrangeBlaze; Oct 12th, 2024 at 11:47 AM.
No, Shaggy Hiker, I am not stealing your signature.
-
Oct 12th, 2024, 11:41 AM
#9
Re: BitBlt from png with transparency
DrawIconEx, this will also cause the picture to be not smooth and blurred when it is zoomed out.
-
Oct 12th, 2024, 11:47 AM
#10
Re: BitBlt from png with transparency
are you messing with me? Im quite tired of this sh*t.
not sure what u are doing but the problem its u. u are doing something wrong.
and if u expect this to work in windows 95/98 of course it will not.
this was introduced with windows 2000 (so it works in xp/vista) u can not expect us to help u with ancient compatibility.
and U need to add that in your OP if u require such things. Im out, can't help people like u.
-
Oct 12th, 2024, 12:02 PM
#11
Re: BitBlt from png with transparency
Originally Posted by OrangeBlaze
Hello baka, I put your code in a new form and it does not work. (hIcon still 0)
I have seen some sites mention that support for PNGs in CreateIconFromResourceEx was added in Vista. Will it not work with previous versions?
Edit: Just tried on Windows 7 and still did not work.
Btw, baka's sample code works beautifully here on Win11.
So you are targeting XP or Win9x? Which one it is?
AlphaBlend API works on XP so does GDI+ for decoding the PNG. Your best bet would be to decode the PNG to a 32-bit alpha transparent DIB (precomputed alpha, so called PARGB pixels) and then AlphaBlend from it into your DC.
You have to use AlphaBlend. You cannot use BitBlt and expect transparency, no idea where your confusion about this API comes from.
cheers,
</wqw>
-
Oct 12th, 2024, 12:27 PM
#12
Re: BitBlt from png with transparency
not sure what u try to do.
but this works in windows 7-11 (I know as I have windows 7 and 10 installed) probably xp-vista as well (but can't say 100% since I don't have those anymore)
the problem is u.
so instead of saying nothing work, show what u are doing. YOUR CODE.
Im sure theres something wrong with that. maybe that PNG is not a PNG at all. who knows.
-
Oct 12th, 2024, 01:11 PM
#13
Re: BitBlt from png with transparency
MSDN does mention that: "Since Windows Vista RT_ICON icon or RT_CURSOR cursor resource may contain PNG-compressed image data."
Just tested this code on Windows 10 and it works correctly (the PNG is drawn on the form):
Code:
Private Declare Function CreateIconFromResourceEx Lib "user32" (presbits As Any, ByVal dwResSize As Long, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
Private Declare Function DrawIconEx Lib "user32" (ByVal hDC As Long, ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long
Private Declare Function DestroyIcon Lib "user32" (ByVal hIcon As Long) As Long
Private Sub Form_Load()
Dim hIcon As Long, baData() As Byte
AutoRedraw = True
With New WIA.ImageFile
.LoadFile "Picture.png"
baData = .FileData.BinaryData
hIcon = CreateIconFromResourceEx(baData(0), .FileData.Count, 1, &H30000, .Width, .Height, 0)
If hIcon Then
DrawIconEx hDC, 0, 0, hIcon, .Width, .Height, 0, 0, 3
DestroyIcon hIcon
End If
End With
End Sub
-
Oct 12th, 2024, 01:51 PM
#14
Re: BitBlt from png with transparency
This works on XP using GDI+
Code:
Option Explicit
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GdiplusStartup Lib "gdiplus" (hToken As Long, pInputBuf As Any, Optional ByVal pOutputBuf As Long = 0) As Long
Private Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal sFileName As Long, mImage As Long) As Long
Private Declare Function GdipGetImageDimension Lib "gdiplus" (ByVal hImage As Long, nWidth As Single, nHeight As Single) As Long '
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal hImage As Long) As Long
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hDC As Long, hGraphics As Long) As Long
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal hGraphics As Long) As Long
Private Declare Function GdipDrawImageRectRect Lib "gdiplus" (ByVal hGraphics As Long, ByVal hImage As Long, ByVal dstX As Single, ByVal dstY As Single, ByVal dstWidth As Single, ByVal dstHeight As Single, ByVal srcX As Single, ByVal srcY As Single, ByVal srcWidth As Single, ByVal srcHeight As Single, Optional ByVal srcUnit As Long = 2, Optional ByVal hImageAttributes As Long, Optional ByVal pfnCallback As Long, Optional ByVal lCallbackData As Long) As Long
Private Sub Form_Load()
AutoRedraw = True
DrawImage App.Path & "\garden.png", hDC
End Sub
Private Sub DrawImage(sFileName As String, ByVal hDC As Long, Optional ByVal lX As Long, Optional ByVal lY As Long)
Dim aInput(0 To 3) As Long
Dim hBitmap As Long
Dim sngWidth As Single
Dim sngHeight As Single
Dim hGraphics As Long
If GetModuleHandle("gdiplus") = 0 Then
aInput(0) = 1
Call GdiplusStartup(0, aInput(0))
End If
Call GdipLoadImageFromFile(StrPtr(sFileName), hBitmap)
Call GdipGetImageDimension(hBitmap, sngWidth, sngHeight)
Call GdipCreateFromHDC(hDC, hGraphics)
Call GdipDrawImageRectRect(hGraphics, hBitmap, lX, lY, sngWidth, sngHeight, 0, 0, sngWidth, sngHeight)
Call GdipDisposeImage(hBitmap)
Call GdipDeleteGraphics(hGraphics)
End Sub
cheers,
</wqw>
-
Oct 12th, 2024, 02:19 PM
#15
Re: BitBlt from png with transparency
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Oct 12th, 2024, 07:05 PM
#16
Thread Starter
Lively Member
Re: BitBlt from png with transparency
Hello all! baka was fed up with me, and no-one else had responded so throughout the entire day I looked for a solution. Just came back here to post it and mark resolved and I see all this. Thank you everyone for your help, I will look into which one of these works best for me. Right now I just got LaVolpe's PNG rendering code working, which is very similiar to wqweto's example, but with much more stuff I don't need.
For right now, my solution is this:
https://www.vbforums.com/showthread....pdated-16Feb09
However I will probably end up using wqweto's code as it is very similiar and this already works like a charm (I expected nothing less from LaVolpe)
No, Shaggy Hiker, I am not stealing your signature.
-
Oct 12th, 2024, 08:56 PM
#17
Thread Starter
Lively Member
Re: BitBlt from png with transparency
Hello again. I got wqweto's solution working perfectly except for one thing. If I don't run any GDI+ code, after I end the program, when the IDE loses focus it crashes. Very annoying. This might be another thread but just posting here for now. It seems like if GdiPlusStartup was ever called, this issue occurs. If it was never called, no issue. But obviously I need GdiPlusStartup.
No, Shaggy Hiker, I am not stealing your signature.
-
Oct 13th, 2024, 02:14 AM
#18
Re: BitBlt from png with transparency
if u use GDI+ u need to initialize it and also close it. especially if u use an older OS (that u should have mentioned)
wqweto code, just edit this part:
Code:
If GetModuleHandle("gdiplus") = 0 Then
aInput(0) = 1
Call GdiplusStartup(0, aInput(0))
End If
with
Code:
If mToken = 0 Then
aInput(0) = 1
GdiplusStartup mToken, aInput(0)
End If
where mToken is a global variable
and when u done using GDI+ (usually in the termination-procedure, before your application ends)
you add:
Code:
GdiplusShutdown mToken
or if u just want to use it one time add it at the end of the function.
-
Oct 13th, 2024, 03:33 PM
#19
Thread Starter
Lively Member
Re: BitBlt from png with transparency
Thank you baka, wqweto, and everyone else! It now works! Here is my final code:
Code:
Private Declare Function GdiplusStartup Lib "gdiplus" (hToken As Long, pInputBuf As Any, Optional ByVal pOutputBuf As Long = 0) As Long
Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As Long
Private Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal sFileName As Long, mImage As Long) As Long
Private Declare Function GdipGetImageDimension Lib "gdiplus" (ByVal hImage As Long, nWidth As Single, nHeight As Single) As Long '
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal hImage As Long) As Long
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hDC As Long, hGraphics As Long) As Long
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal hGraphics As Long) As Long
Private Declare Function GdipDrawImageRectRect Lib "gdiplus" (ByVal hGraphics As Long, ByVal hImage As Long, ByVal dstX As Single, ByVal dstY As Single, ByVal dstWidth As Single, ByVal dstHeight As Single, ByVal srcX As Single, ByVal srcY As Single, ByVal srcWidth As Single, ByVal srcHeight As Single, Optional ByVal srcUnit As Long = 2, Optional ByVal hImageAttributes As Long, Optional ByVal pfnCallback As Long, Optional ByVal lCallbackData As Long) As Long
Dim hBitmap As Long
Dim hGraphics As Long
Dim GDItoken As Long
Public Sub InitGDI()
Dim aInput(0 To 3) As Long
aInput(0) = 1
If GDItoken = 0 Then Call GdiplusStartup(GDItoken, aInput(0))
End Sub
Public Sub DisposeGDI()
Call GdipDeleteGraphics(hGraphics)
Call GdiplusShutdown(GDItoken)
End Sub
Public Sub DrawPNG(ByVal hDC As Long, sFile As String, X As Single, Y As Single, Width As Single, Height As Single)
Dim sngWidth As Single
Dim sngHeight As Single
'Dispose of old handle if exist
If hBitmap <> 0 Then Call GdipDisposeImage(hBitmap)
'Make handle to draw from
Call GdipLoadImageFromFile(StrPtr(sFile), hBitmap)
'Get dimensions
Call GdipGetImageDimension(hBitmap, sngWidth, sngHeight)
'Create hGraphics
Call GdipCreateFromHDC(hDC, hGraphics)
'Draw
Call GdipDrawImageRectRect(hGraphics, hBitmap, X, Y, Width, Height, 0, 0, sngWidth, sngHeight)
End Sub
No, Shaggy Hiker, I am not stealing your signature.
-
Oct 13th, 2024, 04:27 PM
#20
Re: BitBlt from png with transparency
Btw, my original sample above did not use GdiplusShutdown and did not AV on exit.
The way you have "reimplemented" the snippet is outright dangerous and besides it's leaking hGraphics on each call.
You have to cleanup hBitmap and hGraphics inside DrawPNG but it's up to you to (unnecessary) call GdiplusShutdown through (unnecessary) InitGDI and DisposeGDI whenever you see fit.
(Loading and unloading GDIPLUS.DLL is like loading and unloading GDI32.DLL -- no one should be even thinking about doing it in their app)
cheers,
</wqw>
-
Oct 13th, 2024, 04:46 PM
#21
Re: [RESOLVED] BitBlt from png with transparency
no u need to shut it down or it will crash the application.
hgraphic u delete when u are not rendering anymore.
and u delete the himage (bitmap) when not needed anymore.
theres no right or wrong WHEN u do it. but it should be done before termination.
maybe u dont need to do it in windows 10+ but in older OS u NEED to shut it down.
-
Oct 14th, 2024, 05:02 AM
#22
Re: [RESOLVED] BitBlt from png with transparency
> hgraphic u delete when u are not rendering anymore.
You do realize OP is calling Call GdipCreateFromHDC(hDC, hGraphics) on each call to DrawPNG and leaking it into oblivion.
> maybe u dont need to do it in windows 10+ but in older OS u NEED to shut it down.
No, you don't need to shut GDI+ on any OS *if* you don't leak handles.
Now I'll bow out of this discussion but don't run here asking why your GDI+ app is crashing on exit.
cheers,
</wqw>
-
Oct 14th, 2024, 05:31 AM
#23
Re: [RESOLVED] BitBlt from png with transparency
OMG I have worked with GAMES for decades. I KNOW how to handle GDI+
as I have been working with that A LOT before Direct2D. if u didn't shut it down it would crash the application.
not sure how u use it. but u invalidate +10 years of experience saying that.
if u keep calling GdiplusStartup without never calling GdiplusShutdown eventually it will stop working and u get a crash.
the same with almost anything that has initialization. that is why its important with the termination.
I get issues with sounds if I get a few crashes in IDE. eventually the sound stop working. sometimes a IDE restart can help, but sometimes I need to restart windows.
if u dont understand this theres something really wrong with how u code.
of course if u have a compiled .exe, windows can do it FOR YOU. but its lazy to let the OS do it. especially older OS and u don't know how they operate.
the same with your "suggestion" how to terminate bitmaps in some threads. this ugly trend TO NOT release something is dangerous.
following your suggestion creates eventually out of memory errors and can crash the entire OS. sure u can do it many times, as everything seems to work. until it doesn't.
LEARN TO TERMINATE. *facepalm*
-
Oct 14th, 2024, 05:43 AM
#24
Re: [RESOLVED] BitBlt from png with transparency
I would have addressed all your questions but I already bowed out of this unproductive discussion (no one likes to be shouted at in CAPSLOCK) so you can assume you are right on everything you said.
cheers,
</wqw>
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
|