Transparent PNG alpha channel window
-
- User
- Posts: 77
- Joined: Thu Jan 16, 2020 10:47 pm
Transparent PNG alpha channel window
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.
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.
My blog/software site: http://dosaidsoft.com/
Re: Transparent PNG alpha channel window
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
-
- User
- Posts: 77
- Joined: Thu Jan 16, 2020 10:47 pm
Re: Transparent PNG alpha channel window
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.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:
My blog/software site: http://dosaidsoft.com/
Re: Transparent PNG alpha channel window
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:
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:
-
- User
- Posts: 77
- Joined: Thu Jan 16, 2020 10:47 pm
Re: Transparent PNG alpha channel window
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.
My blog/software site: http://dosaidsoft.com/
Re: Transparent PNG alpha channel window
Search for "UpdateLayeredWindow"
Et cetera is my worst enemy
- netmaestro
- PureBasic Bullfrog
- Posts: 8433
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Transparent PNG alpha channel window
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
BERESHEIT
Re: Transparent PNG alpha channel window
@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
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
- netmaestro
- PureBasic Bullfrog
- Posts: 8433
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Transparent PNG alpha channel window
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.
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.
BERESHEIT
Re: Transparent PNG alpha channel window
@netmaestro : thank you for your effort, I can't wait...
- netmaestro
- PureBasic Bullfrog
- Posts: 8433
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Transparent PNG alpha channel window
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.
BERESHEIT
- netmaestro
- PureBasic Bullfrog
- Posts: 8433
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Transparent PNG alpha channel window
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.
BERESHEIT