How to draw transparent text on a bitmap using GDIp?
Re: How to draw transparent text on a bitmap using GDIp?
That would be because they’re not actually white. At least not pure white.
Re: How to draw transparent text on a bitmap using GDIp?
Yes. that was what I was talking about. With 12pt text, almost nothing gets transparent.
Works fine if the written text is thick enough:
Code: Select all
#NoEnv
#Warn
#SingleInstance, Force
Gui, Font, s72 Bold, Consolas
Gui, Add, Text, w400 h250 hWndTXThWnd, Hello World
Gui, Show,
inFile := A_ScriptDir . "\pbitmap.png"
outFile := A_ScriptDir . "\Txt_pBitmap.png"
If ! FileExist(inFile)
UrlDownloadToFile, https://www.autohotkey.com/boards/download/file.php?id=14167, %inFile%
; Load GdiPlus
hMod := DllCall("kernel32.dll\LoadLibrary", "Str","Gdiplus.dll", "Ptr")
VarSetCapacity(GdiplusStartupInput, 24, 0)
NumPut(1, GdiplusStartupInput, "Int")
DllCall("Gdiplus.dll\GdiplusStartup", "PtrP",pToken:=0, "Ptr",&GdiplusStartupInput, "Int",0)
DllCall("Gdiplus.dll\GdipCreateBitmapFromFile", "WStr",inFile, "PtrP",pBitmap:=0)
pBitmap := DrawTXT(pBitmap, "Hello World", TXThWnd, 0xFFFFFFFF, 0xFFFEFEFE, 0x00FFFFFF)
; Save to PNG
VarSetCapacity(CODEC, 16)
NumPut(0x2EF31EF8,NumPut(0x0000739A,NumPut(0x11D31A04,NumPut(0x557CF406, CODEC,"Int"),"Int"),"Int"),"Int")
DllCall("Gdiplus.dll\GdipSaveImageToFile", "Ptr",pBitmap, "WStr",outFile, "Ptr",&CODEC, "Int",0)
; Clean up
DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr",pBitmap)
DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr",pToken)
DllCall("Kernel32.dll\FreeLibrary", "Ptr",hMod)
Return ; -----------------------------------------------
GuiClose:
GuiEscape:
ExitApp
Return
DrawTxt(pBitmap, Txt, Hwnd, OldColor, ReplaceColor, NewColor) {
Local
DllCall("Gdiplus.dll\GdipGetImageWidth", "Ptr",pBitmap, "PtrP",SW:=0)
DllCall("Gdiplus.dll\GdipGetImageHeight","Ptr",pBitmap, "PtrP",SH:=0)
; PARGB := 925707
DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int",SW, "Int",SH, "Int",0, "Int",925707, "Ptr",0, "PtrP",pBitmap2:=0)
VarSetCapacity(COLORMAP, 8)
NumPut(OldColor, COLORMAP, 0, "UInt")
NumPut(ReplaceColor, COLORMAP, 4, "UInt")
DllCall("Gdiplus.dll\GdipCreateImageAttributes", "PtrP",pAttr:=0)
DllCall("Gdiplus.dll\GdipSetImageAttributesRemapTable", "Ptr",pAttr, "Int",0, "Int",1, "Int",2, "Ptr",&COLORMAP)
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr",pBitmap2, "PtrP",pGraphics:=0)
DllCall("Gdiplus.dll\GdipGraphicsClear", "Ptr",pGraphics, "Int",0x0)
DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr",pGraphics, "Ptr",pBitmap
, "Float",0, "Float",0, "Float",SW, "Float",SH, "Float",0, "Float",0, "Float",SW, "Float",SH
, "Int",2, "Ptr",pAttr, "Ptr",0, "Ptr",0 )
DllCall("Gdiplus.dll\GdipDisposeImageAttributes", "Ptr",pAttr)
DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr",pBitmap)
; Create a StringFormat object
DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP",hFormat:=0)
; Fill the text color
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt",OldColor, "PtrP",pBrush:=0)
; 0x01 Center
DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr",hFormat, "Int",0x01)
; Vertical alignment 1 - Middle
DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr",hFormat, "Int",1)
; Set render quality to system default
DllCall("Gdiplus.dll\GdipSetTextRenderingHint", "Ptr",pGraphics, "Int",0)
VarSetCapacity(RECTFLOAT, 16, 0)
NumPut(SW, RECTFLOAT, 8, "Float")
NumPut(SH, RECTFLOAT, 12, "Float")
; Use the FONT from the given control
hFont := DllCall("User32.dll\SendMessage", "Ptr",Hwnd, "UInt",0x31, "Ptr",0, "Ptr",0, "Ptr")
hDC := DllCall("User32.dll\GetDC", "Ptr",Hwnd, "Ptr")
DllCall("Gdi32.dll\SaveDC", "Ptr",hDC)
DllCall("Gdi32.dll\SelectObject", "Ptr",hDC, "Ptr",hFont)
DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr",hDC, "PtrP",pFont:=0)
DllCall("Gdi32.dll\RestoreDC", "Ptr",hDC, "Int",-1)
DllCall("User32.dll\ReleaseDC", "Ptr",Hwnd, "Ptr",hDC)
DllCall("Gdiplus.dll\GdipDrawString", "Ptr",pGraphics, "WStr",Txt, "Int",-1, "Ptr",pFont, "Ptr",&RECTFLOAT, "Ptr",hFormat, "Ptr",pBrush)
DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr",pFont)
DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr",pBrush)
DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr",hFormat)
DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr",pGraphics)
; PARGB := 925707
DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int",SW, "Int",SH, "Int",0, "Int",925707, "Ptr",0, "PtrP",pBitmap3:=0)
NumPut(OldColor, COLORMAP, 0, "UInt")
NumPut(NewColor, COLORMAP, 4, "UInt")
DllCall("Gdiplus.dll\GdipCreateImageAttributes", "PtrP",pAttr:=0)
DllCall("Gdiplus.dll\GdipSetImageAttributesRemapTable", "Ptr",pAttr, "Int",0, "Int",1, "Int",2, "Ptr",&COLORMAP)
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr",pBitmap3, "PtrP",pGraphics:=0)
DllCall("Gdiplus.dll\GdipGraphicsClear", "Ptr",pGraphics, "Int",0)
DllCall("Gdiplus.dll\GdipDrawImageRectRect", "Ptr",pGraphics, "Ptr",pBitmap2
, "Float",0, "Float",0, "Float",SW, "Float",SH, "Float",0, "Float",0, "Float",SW, "Float",SH
, "Int",2, "Ptr",pAttr, "Ptr",0, "Ptr",0 )
DllCall("Gdiplus.dll\GdipDisposeImageAttributes", "Ptr",pAttr)
DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr",pGraphics)
DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr",pBitmap2)
Return pBitmap3
}
Re: How to draw transparent text on a bitmap using GDIp?
@SKAN In the picture you post you can click through the text, the text background just being visible is enough.
In the picture below i can see through the text but can't click through it, i apologize if i didn't make it clear, English is not my main language.
In the picture below i can see through the text but can't click through it, i apologize if i didn't make it clear, English is not my main language.
Spoiler
Re: How to draw transparent text on a bitmap using GDIp?
As i could not find a way to draw the text in the bitmaps with transparency and with a 'good' result, i have been trying to draw it with transparency directly into the DC.
The code above does draw the text correctly with the desired color:
However, when I try to draw the text color with transparency the text is drawn black.
Also, any other method that could draw the text on the dc with transparency would help.
The code above does draw the text correctly with the desired color:
Code: Select all
TextColor := 0xff0000
DllCall("Gdi32.dll\SetTextColor", "Ptr", DC, "UInt", TextColor)
DllCall("User32.dll\DrawText", "Ptr", DC, "Ptr", &Txt, "Int", StrLen(Txt), "Ptr", &RECT, "UInt", TextAlignment )
Code: Select all
TextColor := 0x7DFF0000
;BkColor := 0xff0000
DllCall("Gdi32.dll\SetBkMode", "Ptr", DC, "UInt", 1) ; TRANSPARENT = 1
;DllCall("Gdi32.dll\SetBkColor", "Ptr", DC, "UInt", BkColor)
DllCall("Gdi32.dll\SetTextColor", "Ptr", DC, "UInt", TextColor)
DllCall("User32.dll\DrawText", "Ptr", DC, "Ptr", &Txt, "Int", StrLen(Txt), "Ptr", &RECT, "UInt", TextAlignment )
Re: How to draw transparent text on a bitmap using GDIp?
***Note***fabricio234 wrote:04 Aug 2021, 04:13Hello, sorry dming, i think no one else is able to help, but, could you take a look on this question?
Its about drawing text with transparency on a bitmap.
https://www.autohotkey.com/boards/viewtopic.php?f=76&t=92850&sid=e66c75187879d9e06b043f228a5caad0
I haven't ran / read any other code from this thread, coming in blind.
;******************************************************************************
Window class (needed to run the demo)
Code: Select all
;************************************************************************************************************************************************************************************************
;************************************************************************************************************************************************************************************************
;************************************************************************************************************************************************************************************************
;************************************************************************************************************************************************************************************************
;************************************************************************************************************************************************************************************************
class PopUpWindow {
;Class By: Hellbent
;Apr 2021
static Index := 0 , Windows := [] , Handles := [] , HelpHandles := [] , HelperEditHwnd
__New( obj := "" ){
This._SetDefaults()
if( isObject( obj ) )
This.SetWindowProperties( obj )
This._SetupWindowGraphics()
}
_SetDefaults(){
PopUpWindow.Index++
This.WindowName := "HBLayeredWindow" PopUpWindow.Index
This.WindowSmoothing := 2
This.WindowOptions := " -DPIScale +AlwaysOnTop "
This.X := 10
This.Y := 10
This.W := 10
This.H := 10
}
PaintBackground( color := "0xFF000000" ){
Brush := Gdip_BrushCreateSolid( color )
Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 )
Gdip_DeleteBrush( Brush )
}
_SetupWindowGraphics(){
This.Hwnd := This._CreateGUI()
This.hbm := CreateDIBSection( This.W , This.H )
This.hdc := CreateCompatibleDC()
This.obm := SelectObject( This.hdc , This.hbm )
This.G := Gdip_GraphicsFromHDC( This.hdc )
Gdip_SetSmoothingMode( This.G , This.WindowSmoothing )
PopUpWindow.Handles[ This.Hwnd ] := PopUpWindow.Index
PopUpWindow.Windows[ PopUpWindow.Index ] := This
}
SetWindowProperties( obj , updateG := 0 ){
local k , v
for k , v in obj
if( k != "hwnd" )
This[k] := v
if(updateG){
SelectObject( This.hdc , This.obm )
DeleteObject( This.hbm )
DeleteDC( This.hdc )
This.hbm := CreateDIBSection( This.W , This.H )
This.hdc := CreateCompatibleDC()
This.obm := SelectObject( This.hdc , This.hbm )
This.G := Gdip_GraphicsFromHDC( This.hdc )
Gdip_SetSmoothingMode( This.G , This.WindowSmoothing )
}
( This.X = "center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 )
( This.Y = "center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 )
}
ShowWindow( Title := "" ){
Gui , % This.WindowName ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
}
HideWindow(){
Gui , % This.WindowName ":Hide",
}
UpdateWindow(){
UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
}
ClearWindow(){
Gdip_GraphicsClear( This.G )
}
DrawBitmap( pBitmap , obj , dispose := 1 ){
Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
if( dispose )
Gdip_DisposeImage( pBitmap )
}
DeleteWindow(){
Gui, % This.WindowName ":Destroy"
SelectObject( This.hdc , This.obm )
DeleteObject( This.hbm )
DeleteDC( This.hdc )
Gdip_DeleteGraphics( This.G )
hwnd := This.Hwnd
for k, v in PopUpWindow.Windows[ Hwnd ]
This[k] := ""
PopUpWindow.Windows[ Hwnd ] := ""
}
_CreateGUI(){
local hwnd
Gui , % This.WindowName ":New" , % " +E0x80000 hwndhwnd -Caption " This.WindowOptions
return hwnd
}
Helper(){
local List := ["New Window","SetWindowProperties","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow"]
local hwnd, bd
Gui, HBLWHelperGui:New, +AlwaysOnTop
Gui, HBLWHelperGui:Color, 62666a, 24282c
Gui, HBLWHelperGui:Font, cWhite s10 , Segoe UI
Gui, HBLWHelperGui:Margin, 5 , 5
Gui, HBLWHelperGui:Add, Edit, xm ym w200 r1 Center hwndHwnd, Gui1
PopUpWindow.HelperEditHwnd := Hwnd
Gui, HBLWHelperGui:Margin, 5 , 1
Loop, % List.Length() {
Gui, HBLWHelperGui:Add, Button, xm wp h23 -Theme hwndhwnd, % List[ A_Index ]
PopUpWindow.HelpHandles[hwnd] := List[ A_Index ]
bd := PopUpWindow._ClipIt.Bind( PopUpWindow )
GuiControl , HBLWHelperGui: +G , % Hwnd , % bd
}
Gui, HBLWHelperGui:Show,
}
_ClipIt(){
local List := ["New Window","SetWindowProperties","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow"]
local Output , FQ := 400
GuiControlGet, Output , HBLWHelperGui: , % PopUpWindow.HelperEditHwnd
Switch A_GuiControl
{
case List[1]:
Clipboard := Output " := New PopUpWindow( { WindowName: ""1"" , WindowOptions: "" -DPIScale +AlwaysOnTop "" , WindowSmoothing: 2 , X: ""Center"" , Y: ""Center"" , W: 100 , H: 100 } )"
loop 2
SoundBeep, FQ
return
case List[2]:
Clipboard := Output ".SetWindowProperties( { X: """" , Y: """" , W: """" , H: """" } )"
loop 2
SoundBeep, FQ
return
case List[3]:
Clipboard := Output ".ShowWindow( MyWindowTitle := """" )"
loop 2
SoundBeep, FQ
return
case List[4]:
Clipboard := Output ".HideWindow()"
loop 2
SoundBeep, FQ
return
case List[5]:
Clipboard := Output ".UpdateWindow()"
loop 2
SoundBeep, FQ
return
case List[6]:
Clipboard := Output ".ClearWindow()"
loop 2
SoundBeep, FQ
return
case List[7]:
Clipboard := Output ".DrawBitmap( pBitmap := """" , { X: """" , Y: """" , W: """" , H: """" } , dispose := 1 )"
loop 2
SoundBeep, FQ
return
case List[8]:
Clipboard := Output ".PaintBackground( color := ""0xFF000000"" )"
loop 2
SoundBeep, FQ
return
case List[9]:
Clipboard := Output ".DeleteWindow()"
loop 2
SoundBeep, FQ
return
Default:
ToolTip, Looks like a new case needs to be added
return
}
}
}
Demo code:
Code: Select all
;***************************************************************************************************
#Include <My Altered Gdip Lib> ;Replace with your path to the Gdip.ahk lib
#Include <PopUpWindow Class>
;***************************************************************************************************
#SingleInstance force
SetBatchLines, -1
Gdip_StartUp()
;*************************************************************************************
;Change this stuff ( Font, FontSize, colors, etc)
obj := { X: 0 , Y: 0 , W: 350 , H: 150 , Text: "Hello World" , FontSize: 56 , Font: "Impact" , FontOptions: " Center vCenter "}
SearchColor := "0xFFffffFF"
ReplaceColor := "0x66ffFFFF"
;*************************************************************************************
pBitmap := HB_BITMAP_MAKER( obj , SearchColor )
SetPixels( pBitmap , obj , SearchColor , ReplaceColor , 150 )
Gui1 := New PopUpWindow( { WindowName: "1" , WindowOptions: " -DPIScale +AlwaysOnTop " , WindowSmoothing: 2 , X: "Center" , Y: "Center" , W: obj.W , H: obj.H } )
Gui1.ShowWindow( "Trans Text" )
Gui1.DrawBitmap( pBitmap , obj , 1 )
Gui1.UpdateWindow()
OnMessage( 0x201 , "MoveWindow" )
return
GuiClose:
GuiContextMenu:
*ESC::ExitApp
Numpad3::
PopUpWindow.Helper()
return
MoveWindow(){
PostMessage, 0xA1, 2
}
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;Search and replace pixels of one color ( +/- Tolerance ) to anoter color
SetPixels( pBitmap , obj , SearchColor , ReplaceColor , Tolerance := 0 ){
sRed := SubStr( SearchColor, 5, 2) , sGreen := SubStr( SearchColor, 7, 2) , sBlue := SubStr( SearchColor, 9, 2)
sRed := "0x" sRed , sGreen := "0x" sGreen , sBlue := "0x" sBlue
sRed := sRed+0 , sGreen := sGreen+0 , sBlue := sBlue+0
y := obj.Y
Loop, % obj.H {
x := obj.X
Loop, % obj.W {
SetFormat, IntegerFast, hex
col := Gdip_GetPixel( pBitmap, x , y )
SetFormat, IntegerFast, dec
cRed := SubStr( col, 5, 2) , cGreen := SubStr( col, 7, 2) , cBlue := SubStr( col, 9, 2)
cRed := "0x" cRed , cGreen := "0x" cGreen , cBlue := "0x" cBlue
cRed := cRed+0 , cGreen := cGreen+0 , cBlue := cBlue+0
if( col = SearchColor || ( cRed >= sRed - Tolerance && cRed <= sRed + Tolerance && cGreen >= sGreen - Tolerance && cGreen <= sGreen + Tolerance && cBlue >= sBlue - Tolerance && cBlue <= sBlue + Tolerance ) )
Gdip_SetPixel( pBitmap , x , y , ReplaceColor )
x++
}
y++
}
}
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
HB_BITMAP_MAKER( obj , SearchColor , BackgroundColor := "0xFF222222" ){
;Bitmap Created Using: HB Bitmap Maker
pBitmap := Gdip_CreateBitmap( obj.W , obj.H ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
Brush := Gdip_BrushCreateSolid( BackgroundColor ) , Gdip_FillRectangle( G , Brush , -1 , -1 , obj.W + 2 , obj.H + 2 ) , Gdip_DeleteBrush( Brush )
Brush := Gdip_BrushCreateSolid( SearchColor ) , Gdip_TextToGraphics( G , obj.Text , "s" obj.FontSize " " obj.FontOptions " c" Brush " x" obj.X " y" obj.Y , obj.Font , obj.W , obj.H ) , Gdip_DeleteBrush( Brush )
Gdip_DeleteGraphics( G )
return pBitmap
}
*Edit* Fixed hex > Dec , Dec > Hex conversion.
Re: How to draw transparent text on a bitmap using GDIp?
I added a bit more flexibility with the tolerance of the search color.
Change the alpha of a area of a bitmap. ( Change the transparency of a small region of a bitmap {x, y, w, h} )
Code: Select all
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
LiquidatePixels( pBitmap , obj , SearchColor , ReplaceColor , RThresh := 128 , GThresh := 128 , BThresh := 128 ){
hex2rgb( SearchColor , sRed , sGreen , sBlue )
y := obj.Y
Loop, % obj.H {
x := obj.X
Loop, % obj.W {
SetFormat, IntegerFast, hex
col := Gdip_GetPixel( pBitmap, x , y )
SetFormat, IntegerFast, dec
hex2rgb( col , cRed , cGreen , cBlue )
if( col = SearchColor || ( cRed >= sRed - RThresh && cRed <= sRed + RThresh && cGreen >= sGreen - GThresh && cGreen <= sGreen + GThresh && cBlue >= sBlue - BThresh && cBlue <= sBlue + BThresh ) )
Gdip_SetPixel( pBitmap , x , y , ReplaceColor )
x++
}
y++
}
}
hex2rgb( CR , ByRef R , ByRef G , ByRef B , ByRef A := "NA" ){ ;https://www.autohotkey.com/boards/viewtopic.php?t=3925&p=312862
H := InStr(CR, "0x") ? CR : ( InStr(CR, "#" ) ? "0x" SubStr( CR , 2 ) : "0x" CR )
R := (H & 0xFF0000) >> 16 , G := (H & 0xFF00) >> 8 , B := (H & 0xFF) , ( A != "NA" ) ? ( A := (H & 0xFF000000) >> 24 )
}
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
Change the alpha of a area of a bitmap. ( Change the transparency of a small region of a bitmap {x, y, w, h} )
Code: Select all
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
TransBitmap( pBitmap , obj , Alpha := 128 ){
y := obj.Y
Loop, % obj.H {
x := obj.X
Loop, % obj.W {
SetFormat, IntegerFast, hex
col := Gdip_GetPixel( pBitmap, x , y )
col := SubStr( col , 5 )
Gdip_SetPixel( pBitmap , x , y , Alpha col )
SetFormat, IntegerFast, dec
x++
}
y++
}
}
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************
;****************************************************************************************************************************************************************************************