Page 1 of 2
Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 1:56 am
by OgreVorbis
I've found many posts regarding this by searching, but none of them seem to do what I'm looking for.
Currently, I'm using SetLayeredWindowAttributes with LWA_COLORKEY. This only allows me to have a certain color be fully transparent. What I want to do is display a PNG with an alpha channel in a boarderless window and have the alpha parts be partially transparent. In simpler terms, I want to display a transparent PNG exactly as it should look. There are no controls on the form other than an image gadget currently.
There's also the LWA_ALPHA option, but apparently that just makes the whole window partially transparent. My goal is something like the program called Rainmeter.
Side question: If I'm able to achieve this, does drawing on the alpha PNG with 2D drawing functions void the alpha channel? Cause I want to draw extra stuff on top of the PNG programmatically. The extra stuff does not need to be transparent though.
Re: Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 5:36 am
by BarryG
What do you mean? I display transparent PNGs with its alpha channel transparent all the time. Is that what you mean? You still need #LWA_COLORKEY to make the
window transparent, but the color used for that doesn't have to match the alpha channel of the PNG. Just load the PNG and show it on the transparent window, like this:
Code: Select all
UsePNGImageDecoder()
LoadImage(0,"My_Transparent_PNG_Image.png")
OpenWindow(0,200,65,400,300,"test",#PB_Window_BorderLess)
StickyWindow(0,1)
hWnd=WindowID(0)
SetWindowColor(0,#Blue) ; Color used by #LWA_COLORKEY below (not the PNG's alpha channel).
SetWindowLongPtr_(hWnd,#GWL_EXSTYLE,GetWindowLongPtr_(hWnd,#GWL_EXSTYLE)|#WS_EX_LAYERED)
SetLayeredWindowAttributes_(hWnd,#Blue,0,#LWA_COLORKEY)
ImageGadget(0,10,10,0,0,ImageID(0))
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
Re: Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 7:31 am
by OgreVorbis
BarryG wrote: Sat Mar 05, 2022 5:36 am
What do you mean? I display transparent PNGs with its alpha channel transparent all the time. Is that what you mean? You still need #LWA_COLORKEY to make the
window transparent, but the color used for that doesn't have to match the alpha channel of the PNG. Just load the PNG and show it on the transparent window, like this:
I tried that with one of my PNGs and it doesn't work. It's only fully transparent or not transparent. As I said, it needs to be partially transparent. Could you please upload the PNG you used for the test because it's not working for me. Maybe there is something wrong with my PNG file. It's made with paint.net and displays proper transparency in other image programs.
Re: Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 7:44 am
by BarryG
I don't know if uploading it somewhere will re-encode the PNG, so I put it in a zip file here:
https://drive.google.com/file/d/1kYhEIw ... sp=sharing
Run it with my test code above, and this is how it appears on my desktop:

Re: Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 7:57 am
by OgreVorbis
BarryG wrote: Sat Mar 05, 2022 7:44 am
Run it with my test code above, and this is how it appears on my desktop:
You must not understand the question. What you are showing me has already been done.
The problem is it doesn't work with PARTIAL transparency. Open that image in paint.net or equivalent software and apply a transparency level of 128 for example, you will see it is NOT transparent.
Re: Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 8:14 am
by BarryG
OgreVorbis wrote: Sat Mar 05, 2022 7:57 amYou must not understand the question.
Sorry!
Re: Transparent PNG alpha channel window
Posted: Sat Mar 05, 2022 8:49 am
by chi
Search for "UpdateLayeredWindow"
Re: Transparent PNG alpha channel window
Posted: Mon Mar 07, 2022 6:52 am
by netmaestro
Try this out:
Code: Select all
; Requires PB 5.10 or newer
Declare PreMultiply(image)
CreateImage(0,64,64,32,#PB_Image_Transparent)
StartVectorDrawing(ImageVectorOutput(0))
AddPathBox(0,0,64,64)
VectorSourceColor(RGBA(255,0,0,128))
FillPath()
AddPathBox(16,16,32,32)
VectorSourceColor(RGBA(0,0,255,255))
FillPath()
StopVectorDrawing()
;PreMultiply(0) ; Only use this if the image is brought in with UsePngImageDecoder()
OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TOOLWINDOW)
hDC = StartDrawing(ImageOutput(0))
With sz.SIZE
\cx = ImageWidth(0)
\cy = ImageHeight(0)
EndWith
With BlendMode.BLENDFUNCTION
\SourceConstantAlpha = 255
\AlphaFormat = 1
EndWith
UpdateLayeredWindow_(WindowID(0),0,0,@sz,hDC,@ContextOffset.POINT,0,@BlendMode,2)
StopDrawing()
Repeat
ev=WaitWindowEvent()
Select ev
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
Case #PB_Event_RightClick
CloseWindow(0)
End
EndSelect
Until ev = #PB_Event_CloseWindow
Procedure PreMultiply(image)
StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels)
For j=0 To ImageHeight(image)-1
For i=0 To ImageWidth(image)-1
color = Point(i,j)
Plot(i,j, RGBA(Red(color) & $FF * Alpha(color) & $FF / $FF,
Green(color) & $FF * Alpha(color) & $FF / $FF,
Blue(color) & $FF * Alpha(color) & $FF / $FF,
Alpha(color)))
Next
Next
StopDrawing()
EndProcedure
Re: Transparent PNG alpha channel window
Posted: Thu May 05, 2022 12:37 pm
by punak
@netmaestro : thanks for your codes, I think these codes have the potential to make aero glass windows.

now i want to create a frosted glass window. what changes should be made to the code for this purpose?
like this :
i use this image:
https://www.pngkit.com/view/u2t4r5y3e6u ... ffect-png/
and this codes
Code: Select all
Enumeration
#GlassWin
#ControlsWin
#AeroGlassImg
#CalendarGadget
EndEnumeration
Declare PreMultiply(image)
Define ev, hdc, sz.SIZE, BlendMode.BLENDFUNCTION, ContextOffset.POINT
UsePNGImageDecoder()
LoadImage(#AeroGlassImg,"a.png")
Procedure ControlsWinCB()
ResizeWindow(#ControlsWin,WindowX(#GlassWin), WindowY(#GlassWin), WindowWidth(#GlassWin), WindowHeight(#GlassWin))
EndProcedure
PreMultiply(#AeroGlassImg)
OpenWindow(#GlassWin,0,0,ImageWidth(#AeroGlassImg),ImageHeight(#AeroGlassImg),"",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
SetWindowLongPtr_(WindowID(#GlassWin), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(#GlassWin), #GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TOOLWINDOW)
StickyWindow(#GlassWin, #True)
hDC = StartDrawing(ImageOutput(#AeroGlassImg))
With sz
\cx = ImageWidth(#AeroGlassImg)
\cy = ImageHeight(#AeroGlassImg)
EndWith
With BlendMode
\SourceConstantAlpha = 255
\AlphaFormat = 1
EndWith
UpdateLayeredWindow_(WindowID(#GlassWin),0,0,@sz,hDC,@ContextOffset,0,@BlendMode,2)
StopDrawing()
OpenWindow(#ControlsWin, WindowX(#GlassWin), WindowY(#GlassWin), WindowWidth(#GlassWin), WindowHeight(#GlassWin), "", #PB_Window_BorderLess|#PB_Window_Invisible,WindowID(#GlassWin))
SetWindowColor(#ControlsWin, #Green)
SetWindowLong_(WindowID(#ControlsWin), #GWL_EXSTYLE, #WS_EX_LAYERED|#WS_EX_TOPMOST)
SetLayeredWindowAttributes_(WindowID(#ControlsWin), #Green, 255, #LWA_COLORKEY)
CalendarGadget(#CalendarGadget,100,100,250,200)
HideWindow(#ControlsWin, #False)
BindEvent(#PB_Event_MoveWindow,@ControlsWinCB())
SetActiveWindow(#GlassWin)
Repeat
ev=WaitWindowEvent()
Select ev
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(#GlassWin), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
Case #PB_Event_RightClick
CloseWindow(#ControlsWin)
CloseWindow(#GlassWin)
End
EndSelect
Until ev = #PB_Event_CloseWindow
Procedure PreMultiply(image)
StartDrawing(ImageOutput(image))
DrawingMode(#PB_2DDrawing_AllChannels)
For j=0 To ImageHeight(image)-1
For i=0 To ImageWidth(image)-1
color = Point(i,j)
Plot(i,j, RGBA(Red(color) & $FF * Alpha(color) & $FF / $FF,
Green(color) & $FF * Alpha(color) & $FF / $FF,
Blue(color) & $FF * Alpha(color) & $FF / $FF,
Alpha(color)))
Next
Next
StopDrawing()
EndProcedure
Re: Transparent PNG alpha channel window
Posted: Thu May 05, 2022 6:50 pm
by netmaestro
I am working on a demo code for you, should be ready sometime in the next day or so. In the meantime, here's the basic method in a nutshell:
1. Create a transparent image of the desired dimensions
2. Draw a white box to it with an alpha value of around 140 (or whatever looks good to you). A slight tint might be desirable, up to you.
3. Decide where on the screen you want your frosted glass
4. Take a screenshot of this rectangle
5. Apply a gaussian blur to the screenshot
6. Create an output image same size
7. Draw the blurred image on it
8. Draw the alpha image on it
9. Render the output image to the screen
The result will be a rectangle with a frosted glass appearance, with contents under the glass looking somewhat blurry. If you draw a bathroom or something this could go over top of it in case anyone goes in there. Anyway look for some demo code in the next day or two.
As I am almost criminally lazy I'm going to wait until Keya isn't looking and steal his blur code from:
https://www.purebasic.fr/english/viewtopic.php?p=577063
Because he did an excellent job and I'm tired of reinventing wheels.
Re: Transparent PNG alpha channel window
Posted: Fri May 06, 2022 1:37 pm
by punak
@netmaestro : thank you for your effort, I can't wait...

Re: Transparent PNG alpha channel window
Posted: Fri May 06, 2022 3:44 pm
by acreis
Me too
Re: Transparent PNG alpha channel window
Posted: Sat May 07, 2022 6:58 am
by BarryG
+1
Re: Transparent PNG alpha channel window
Posted: Mon May 09, 2022 4:22 pm
by netmaestro
I'm still fighting to achieve this. I've been on it all weekend with only limited success. There are two basic problems: 1) How to achieve faster performance for the blur and 2) How to grab a screenshot beneath my own window without including my window in it. Microsoft made a perfect solution in Vista with the DwmEnableBlurBehindWindow function (dwmapi.dll) and screenshots of it working look excellent. But while the API runs successfully it no longer blurs the area behind the window starting with Windows 8 because they changed the way windows are drawn. If anyone is able to assist with either of these two issues, your input would be very welcome. I'm not giving up on this.
Re: Transparent PNG alpha channel window
Posted: Mon May 09, 2022 10:14 pm
by netmaestro
Okay I have a couple of ideas. On the blur speed, I've submitted Keya's blur code to wilbert, if he can't speed it up no one can. On screenshotting the area under my window without including my window I can remove the whole client area using SetWindowRgn_() and my client area bits can't interfere with anything if they aren't there. Starting to look hopeful now.