dxgi is pretty good if not for having to port so much ugly com code
its easier to just write a dll wrapper instead
Create an HBitmap with transparency Topic is solved
-
- Posts: 4334
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Create an HBitmap with transparency
If I tell my customers “forget about legacy OS”, they will answer “forget about money”.
Another interesting example:
Code: Select all
width := 40
height := width*7
Gui, -DPIScale
Gui, Margin, 0, 0
for k, v in [0xFF0000, 0xFFA500, 0xFFFF00, 0x66FF00, 0xBFFF, 0x80, 0x800080, 0xFF0000] {
Loop 2
Gui, Add, Pic, % "BackgroundTrans y0 x" . width*(k - A_Index), % "HBITMAP:" . CreateColoredBitmapEx(width, height, v, A_Index - 1)
}
Gui, Show, % "w" . width*7
Return
GuiClose() {
ExitApp
}
CreateColoredBitmapEx(width, height, color, gradient := false) {
hBitmap := CreateDIBSection(width, -height,, pBits)
Loop % height {
i := A_Index - 1
Loop % width
NumPut(gradient ? (color & 0xFFFFFF)|(255/width*A_Index)<<24 : color, pBits + (width*i + A_Index - 1)*4, "UInt")
}
Return hBitmap
}
CreateDIBSection(w, h, bpp := 32, ByRef ppvBits := 0)
{
hdc := DllCall("GetDC", "Ptr", 0, "Ptr")
VarSetCapacity(bi, 40, 0)
NumPut( 40, bi, 0, "UInt")
NumPut( w, bi, 4, "UInt")
NumPut( h, bi, 8, "UInt")
NumPut( 1, bi, 12, "UShort")
NumPut( 0, bi, 16, "UInt")
NumPut(bpp, bi, 14, "UShort")
hbm := DllCall("CreateDIBSection", "Ptr", hdc, "Ptr", &bi, "UInt", 0, "PtrP", ppvBits, "Ptr", 0, "UInt", 0, "Ptr")
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdc)
return hbm
}
Last edited by teadrinker on 18 May 2020, 05:40, edited 1 time in total.
Re: Create an HBitmap with transparency
Then You can use Direct2D.If I tell my customers “forget about legacy OS”, they will answer “forget about money”.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Create an HBitmap with transparency
С AlphaBlend на AutoHotkey не встречал рабочих примеров, только обсуждения что что то не получается.
dxgi по моему очень сложен в освоении тем более на AutoHotkey, а нормальная обёртка тем более в виде Dll маловероятно что будет сделана.
На Windows 10 конечно очень удобно и просто использовать LayeredChild, но с поддержкой Windows 7 это будет 2 разных кода.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Create an HBitmap with transparency
Я также искал, но не вижу что можно просто запустить и увидеть результат.
Re: Create an HBitmap with transparency
Hi @serzh82saratov : Just a friendly reminder to use english in this part of the forum .
Thank you!
Thank you!
-
- Posts: 4334
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Create an HBitmap with transparency
An AlphaBlend example. Here we create a DC with opaque green, that is overlapped with a DC with a blue color containing a gradient alpha channel.
I would say it is not too convenient method since we have to pre-multiply the color channels.
Code: Select all
#NoEnv
SetBatchLines, -1
hBitmap := DrawGradient(0x66FF00, 0xBFFF, 300, 300, "v")
Gui, Margin, 0, 0
Gui, Add, Pic,, HBITMAP:%hBitmap%
Gui, Show
Return
GuiClose() {
ExitApp
}
DrawGradient(colorRGB_1, colorRGB_2, width, height, direction) {
Loop 2 {
k := A_Index
hBitmap%k% := CreateDIBSection(width, height,, pBits%k%)
Loop % height {
i := A_Index - 1
Loop % width {
if (k = 1)
color := colorRGB_1 | 0xFF000000
else {
alpha := 255/(direction = "h" ? width/A_Index : height/(i + 1))
r := (colorRGB_2 >> 16)*alpha/0xFF << 16
g := ((colorRGB_2 >> 8) & 0xFF)*alpha/0xFF << 8
b := (colorRGB_2 & 0xFF)*alpha/0xFF
color := (alpha << 24) | r | g | b
}
NumPut(color, pBits%k% + (width*i + A_Index - 1)*4, "UInt")
}
}
hDC%k% := DllCall("CreateCompatibleDC", "Ptr", 0, "Ptr")
obj%k% := DllCall("SelectObject", "Ptr", hDC%k%, "Ptr", hBitmap%k%)
}
DllCall("GdiAlphaBlend", "Ptr", hDC1, "Int", 0, "Int", 0, "Int", width, "Int", height
, "Ptr", hDC2, "Int", 0, "Int", 0, "Int", width, "Int", height
, "UInt", 255 << 16 | 1 << 24)
Loop 2 {
DllCall("SelectObject", "Ptr", hDC%A_Index%, "Ptr", obj%A_Index%)
DllCall("DeleteDC", "Ptr", hDC%A_Index%)
}
DllCall("DeleteObject", "Ptr", hBitmap2)
Return hBitmap1
}
CreateDIBSection(w, h, bpp := 32, ByRef ppvBits := 0)
{
hdc := DllCall("GetDC", "Ptr", 0, "Ptr")
VarSetCapacity(bi, 40, 0)
NumPut( 40, bi, 0, "UInt")
NumPut( w, bi, 4, "UInt")
NumPut( h, bi, 8, "UInt")
NumPut( 1, bi, 12, "UShort")
NumPut( 0, bi, 16, "UInt")
NumPut(bpp, bi, 14, "UShort")
hbm := DllCall("CreateDIBSection", "Ptr", hdc, "Ptr", &bi, "UInt", 0, "PtrP", ppvBits, "Ptr", 0, "UInt", 0, "Ptr")
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdc)
return hbm
}
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Create an HBitmap with transparency
I would say that this is a very expensive method, 10 such small pictures will be created for a very long time.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
-
- Posts: 4334
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Create an HBitmap with transparency
Optimized a bit:
Code: Select all
#NoEnv
SetBatchLines, -1
hBitmap := DrawGradient(0x66FF00, 0xBFFF, 300, 300, "v")
Gui, Margin, 0, 0
Gui, Add, Pic,, HBITMAP:%hBitmap%
Gui, Show
Return
GuiClose() {
ExitApp
}
DrawGradient(colorRGB_1, colorRGB_2, width, height, direction) {
colorRGB_1 |= 0xFF000000
r := colorRGB_2 >> 16
g := (colorRGB_2 >> 8) & 0xFF
b := colorRGB_2 & 0xFF
Loop 2 {
k := A_Index
hBitmap%k% := CreateDIBSection(width, height,, pBits%k%)
Loop % height {
i := A_Index
Loop % width {
if (k = 1)
color := colorRGB_1
else {
alpha := 255/(direction = "h" ? width/A_Index : height/i)
factor := alpha/0xFF
color := alpha << 24 | r*factor << 16 | g*factor << 8 | b*factor
}
NumPut(color, pBits%k% + (width*(i - 1) + A_Index - 1)*4, "UInt")
}
}
hDC%k% := DllCall("CreateCompatibleDC", "Ptr", 0, "Ptr")
obj%k% := DllCall("SelectObject", "Ptr", hDC%k%, "Ptr", hBitmap%k%)
}
DllCall("GdiAlphaBlend", "Ptr", hDC1, "Int", 0, "Int", 0, "Int", width, "Int", height
, "Ptr", hDC2, "Int", 0, "Int", 0, "Int", width, "Int", height
, "UInt", 255 << 16 | 1 << 24)
Loop 2 {
DllCall("SelectObject", "Ptr", hDC%A_Index%, "Ptr", obj%A_Index%)
DllCall("DeleteDC", "Ptr", hDC%A_Index%)
}
DllCall("DeleteObject", "Ptr", hBitmap2)
Return hBitmap1
}
CreateDIBSection(w, h, bpp := 32, ByRef ppvBits := 0)
{
hdc := DllCall("GetDC", "Ptr", 0, "Ptr")
VarSetCapacity(bi, 40, 0)
NumPut( 40, bi, 0, "UInt")
NumPut( w, bi, 4, "UInt")
NumPut( h, bi, 8, "UInt")
NumPut( 1, bi, 12, "UShort")
NumPut( 0, bi, 16, "UInt")
NumPut(bpp, bi, 14, "UShort")
hbm := DllCall("CreateDIBSection", "Ptr", hdc, "Ptr", &bi, "UInt", 0, "PtrP", ppvBits, "Ptr", 0, "UInt", 0, "Ptr")
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdc)
return hbm
}
Re: Create an HBitmap with transparency
Use RtlMoveMemory and two unnested loops. One loop to create the width, and a second loop to copy the first over the height. NumPut is too slow.teadrinker wrote: ↑12 May 2020, 14:05Perhaps you want something like this:Edited (2 times)Code: Select all
colorWithoutTransparency := 0xC0C0C0 colorWithTransparency := 0x55F000FF width := 200 height := 200 Gui, Color, FAD886 Gui, Margin, 0, 0 Gui, Add, Pic,, % "HBITMAP:" . CreateColoredBitmap(width, height, colorWithoutTransparency) Gui, Add, Pic, x100 y100 BackgroundTrans, % "HBITMAP:" . CreateColoredBitmap(width, height, colorWithTransparency) Gui, Show CreateColoredBitmap(width, height, color) { hBitmap := CreateDIBSection(width, -height,, pBits) Loop % height { i := A_Index - 1 Loop % width NumPut(color, pBits + width*4*i + (A_Index - 1)*4, "UInt") } Return hBitmap } CreateDIBSection(w, h, bpp := 32, ByRef ppvBits := 0) { hdc := DllCall("GetDC", "Ptr", 0, "Ptr") VarSetCapacity(bi, 40, 0) NumPut( 40, bi, 0, "UInt") NumPut( w, bi, 4, "UInt") NumPut( h, bi, 8, "UInt") NumPut( 1, bi, 12, "UShort") NumPut( 0, bi, 16, "UInt") NumPut(bpp, bi, 14, "UShort") hbm := DllCall("CreateDIBSection", "Ptr", hdc, "Ptr", &bi, "UInt", 0, "PtrP", ppvBits, "Ptr", 0, "UInt", 0, "Ptr") DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdc) return hbm }
Also your color value should take a ARGB value and premultiply it to get pARGB. [alpha, alpha*red, alpha*green, alpha*blue]
-
- Posts: 4334
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Create an HBitmap with transparency
I've already guessed about it. But this method works only if there ara identical lines in the bitmap.
Not sure I understand what you mean. Why is it needed in this case?
Who is online
Users browsing this forum: tar and 94 guests