How to draw transparent text on a bitmap using GDIp?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

How to draw transparent text on a bitmap using GDIp?

20 Jul 2021, 11:22

This is so far what i already got:

Code: Select all

;#include Gdip.ahk

Gui, Font, s12, Consolas
Gui, Add, Text, hWndTXThWnd, Hello World
Gui, Show, w200 h100

pBitmap := Gdip_CreateBitmapFromFile("pbitmap.png")
DrawTXT(PBITMAP, "Hello World", 0xFFFFFF, TXThWnd)
Gdip_SaveBitmapToFile(pBitmap, "Txt_pBitmap.png", 100)
Return

DrawTxt(PBITMAP, TXT, TXTCOLOR, HWND) {

   ; Get the pointer to the bitmap graphics.
   DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", PBITMAP, "PtrP", PGRAPHICS)
   
   ; Create a StringFormat object
   DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", HFORMAT)

   ; Fill the text color
   TxtColor       := GetARGB(TxtColor)
   DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", TxtColor, "PtrP", PBRUSH)

   ; 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(RECT, 16, 0)
   NumPut(0, RECT,  0, "Float")
   NumPut(0, RECT, 4, "Float")

   DllCall("gdiplus\GdipGetImageDimension", Ptr, pBitmap, "Float*", W, "Float*", H)
   NumPut(W, RECT,  8, "Float")
   NumPut(H, RECT, 12, "Float")

   ; Use the FONT from the given control
   HFONT := DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x31, "Ptr",  0, "Ptr", 0, "Ptr")
   DC := DllCall("User32.dll\GetDC", "Ptr", HWND, "Ptr")
   DllCall("Gdi32.dll\SelectObject", "Ptr", DC, "Ptr", HFONT)
   DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr", DC, "PtrP", PFONT)
   DllCall("User32.dll\ReleaseDC", "Ptr", HWND, "Ptr", DC)
   DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", HFONT)

   DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", Txt, "Int",   -1, "Ptr", PFONT, "Ptr", &RECT, "Ptr", HFORMAT, "Ptr", PBRUSH)
   ;DeleteObject(PFONT)
   DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH)
   DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr", HFORMAT)
   DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", PGRAPHICS) 
  
}

GetARGB(RGB) {
   ARGB := This.HTML.HasKey(RGB) ? This.HTML[RGB] : RGB
   Return (ARGB & 0xFF000000) = 0 ? 0xFF000000 | ARGB : ARGB
}
It does draw the text on the image using the font from the given control hWnd:
Txt_pBitmap.png
Txt_pBitmap.png (1.06 KiB) Viewed 1703 times

Does someone know how to draw the text with transparency? (just transparency on text not on the image)
It would look like this: (this one the text is at 70% of transparency)
trans.png
trans.png (1.13 KiB) Viewed 1684 times
Spoiler
Last edited by c7aesa7r on 20 Jul 2021, 15:46, edited 1 time in total.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDI?

20 Jul 2021, 15:15

c7aesa7r wrote:
20 Jul 2021, 11:22
How to draw transparent text on a bitmap using GDI?
Did you mean GdiPlus?
GDI neither supports true transparency nor anti-aliasing.
Text would look ugly if we were to try to work-around a solution.

I can help you with GdiPlus. Let me know.
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDI?

20 Jul 2021, 15:46

@SKAN yes, sorry my mistake, its GDIp. Im gonna edit the title.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDI?

20 Jul 2021, 16:57

c7aesa7r wrote:
20 Jul 2021, 15:46
@SKAN yes, sorry my mistake, its GDIp. Im gonna edit the title.
Okay.
I won't use GDIP.ahk
I am unable to get your code working by replacing the GDIP.ahk function references with direct DllCalls.
The created image is blank i.e, without text.

One suggestion:
Try replacing

Code: Select all

  TxtColor       := GetARGB(TxtColor)
with

Code: Select all

  TxtColor       :=  0xB3FFFFFF
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDIp?

20 Jul 2021, 18:18

Code: Select all

pToken := Gdip_Startup()

Gui, Font, s12, Consolas
Gui, Add, Text, hWndTXThWnd, Hello World
Gui, Show, w200 h100


File = %A_ScriptDir%\pbitmap.png
DllCall("gdiplus\GdipCreateBitmapFromFile", "uint", File, "uint*", pBitmap)

DrawTXT(PBITMAP, "Hello World", 0xB3FFFFFF, TXThWnd)

Gdip_SaveBitmapToFile(pBitmap, "txt_pbitmap.png", 100)
Return



DrawTxt(PBITMAP, TXT, TXTCOLOR, HWND) {

   ; Get the pointer to the bitmap graphics.
   DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", PBITMAP, "PtrP", PGRAPHICS)
   
   ; Create a StringFormat object
   DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", HFORMAT)

   ; Fill the text color
   ;TxtColor      := GetARGB(TxtColor)
   TxtColor       := 0xB3FFFFFF
   DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", TxtColor, "PtrP", PBRUSH)

   ; 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(RECT, 16, 0)
   NumPut(0, RECT,  0, "Float")
   NumPut(0, RECT, 4, "Float")

   DllCall("gdiplus\GdipGetImageDimension", Ptr, pBitmap, "Float*", W, "Float*", H)
   FileAppend, W: %W% H: %H%`n,*
   NumPut(W, RECT,  8, "Float")
   NumPut(H, RECT, 12, "Float")

   ; Use the FONT from the given control
   HFONT := DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x31, "Ptr",  0, "Ptr", 0, "Ptr")
   DC := DllCall("User32.dll\GetDC", "Ptr", HWND, "Ptr")
   DllCall("Gdi32.dll\SelectObject", "Ptr", DC, "Ptr", HFONT)
   DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr", DC, "PtrP", PFONT)
   DllCall("User32.dll\ReleaseDC", "Ptr", HWND, "Ptr", DC)
   DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", HFONT)

   DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", Txt, "Int",   -1, "Ptr", PFONT, "Ptr", &RECT, "Ptr", HFORMAT, "Ptr", PBRUSH)
   ;DeleteObject(PFONT)
   DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH)
   DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr", HFORMAT)
   DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", PGRAPHICS) 
  
}



GetARGB(RGB) {
   ARGB := This.HTML.HasKey(RGB) ? This.HTML[RGB] : RGB
   Return (ARGB & 0xFF000000) = 0 ? 0xFF000000 | ARGB : ARGB
}



Gdip_Startup(multipleInstances:=0) { 
   Static Ptr := "UPtr" 
   pToken := 0 
   If (multipleInstances=0) 
   {
      if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr) 
         DllCall("LoadLibrary", "str", "gdiplus") 
   } Else DllCall("LoadLibrary", "str", "gdiplus") 

   VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1) 
   DllCall("gdiplus\GdiplusStartup", "UPtr*", pToken, Ptr, &si, Ptr, 0) 
return pToken 
}

Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality:=75) { 
   Static Ptr := "UPtr" 
   nCount := 0 
   nSize := 0 
   _p := 0 

   SplitPath sOutput,,, Extension 
   If !RegExMatch(Extension, "^(?i:BMP|DIB|RLE|JPG|JPEG|JPE|JFIF|GIF|TIF|TIFF|PNG)$") 
      Return -1 

   Extension := "." Extension 
   DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize) 
   VarSetCapacity(ci, nSize) 
   DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci) 
   If !(nCount && nSize) 
      Return -2 

   If (A_IsUnicode) {
      StrGet_Name := "StrGet" 
      N := (A_AhkVersion < 2) ? nCount : "nCount" 
      Loop %N% 
      {
         sString := %StrGet_Name%(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16") 
         If !InStr(sString, "*" Extension) 
            Continue 

         pCodec := &ci+idx 
         Break 
      }
   } 
   Else {
      N := (A_AhkVersion < 2) ? nCount : "nCount" 
      Loop %N% 
      {
         Location := NumGet(ci, 76*(A_Index-1)+44) 
         nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int", 0, "uint", 0, "uint", 0) 
         VarSetCapacity(sString, nSize) 
         DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "str", sString, "int", nSize, "uint", 0, "uint", 0) 
         If !InStr(sString, "*" Extension) 
            Continue 

         pCodec := &ci+76*(A_Index-1) 
         Break 
      }
   }

   If !pCodec 
      Return -3 

   If (Quality!=75) {
      Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality 
      If (quality>90) 
         Quality := 90 

      If RegExMatch(Extension, "^\.(?i:JPG|JPEG|JPE|JFIF)$") 
      {
         DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize) 
         VarSetCapacity(EncoderParameters, nSize, 0) 
         DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters) 
         nCount := NumGet(EncoderParameters, "UInt") 
         N := (A_AhkVersion < 2) ? nCount : "nCount" 
         Loop %N% 
         {
            elem := (24+A_PtrSize)*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0) 
            If (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6) 
            {
               _p := elem+&EncoderParameters-pad-4 
               NumPut(Quality, NumGet(NumPut(4, NumPut(1, _p+0)+20, "UInt")), "UInt") 
               Break 
            }
         }
      }
   }

   _E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, "WStr", sOutput, Ptr, pCodec, "uint", _p ? _p : 0) 
Return _E ? -5 : 0 
}

I have added the functions it was missing, its just Gdip_SaveBitmapToFile() and Gdip_Startup().
I did what you suggested, which result in this image:
Spoiler
Comparing it with the image on my first post where i wrote (It would look like this) the text is not 'visible trought'.

Its because the transparency too need to be applied to the background of the image?
Last edited by c7aesa7r on 20 Jul 2021, 18:40, edited 1 time in total.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDIp?

20 Jul 2021, 18:39

c7aesa7r wrote:
20 Jul 2021, 18:18
I have added the functions it was missing, its just Gdip_SaveBitmapToFile() and Gdip_Startup().
Still not working, I found the problem though.

DllCall("gdiplus\GdipCreateBitmapFromFile", "uint", File, "uint*", pBitmap)
c7aesa7r wrote:
20 Jul 2021, 18:18
Comparing it with the image on my first post, the 'text is not visible trought', its because the background of the image?
All I can say is that my suggestion is working correctly.
Try with a large picture and bold text.
The B3 in color 0xB3FFFFFF is 179 i.e., 70% of 255.
The text is correctly drawn @ 70% opacity when I used my avatar instead of your black PNG.
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDIp?

20 Jul 2021, 18:52

In this example the transparency is also applied to the background, my goal is apply it just on the text.
Spoiler

I did this picture using a code i write by 'studying' your Imagen() function.

Code: Select all

pBitmap := Gdip_CreateBitmapFromFile("pbitmap.png")
DrawTXT(PBITMAP, "Hello World", 0xFFFFFF, TXThWnd)
Transparency(pBitmap, 50)
Gdip_SaveBitmapToFile(pBitmap, "x_2.png", 100)

; Set transparency on the image.
Transparency(pBitmap, Transparency) {  
      
   ; Imagen v3.22 by SKAN on D07L/D46D @ tiny.cc/IMAGEN
   ; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=82005

   ;Local ; Requires AutoHotkey v1.1.33.02 +
   Static GdiplusStartupInput, RECT


   If !VarSetCapacity(GdiplusStartupInput)
      VarSetCapacity(GdiplusStartupInput, 24, 0),  NumPut(1,   GdiplusStartupInput, "Int")

   hMod := DllCall("kernel32.dll\LoadLibrary", "Str","GdiPlus.dll", "Ptr")
   pToken := 0
   DllCall("gdiplus.dll\GdiplusStartup", "PtrP",pToken, "Ptr",&   GdiplusStartupInput, "Int",0)

   pGraphics := 0, pAttr := 0      
   BG := 0x00000000

   ; Normal
   X :=  "0000803f00000000000000000000000000000000000000000000803f00000000000000000000  000000000000000000000000803f00000000000000000000000000000000000000000000803f0   0000000000000000000000000000000000000000000803f"

   CM := ""
   VarSetCapacity(CM,100,0)

   X:=DllCall("Crypt32.dll\CryptStringToBinary", "Str",X, "Int",200, "Int",4,    "Ptr",&CM, "IntP",100, "Int",0, "Int",0)

   Z := Format("{:0.7f}", Transparency)
   If ( Z>0 && Z<255 )
         NumPut(Z/255, CM, 72, "Float")

   ; A clone is need here before SetImageAttributesColorMatrix
   ; is applied (transparency), it will be used on 
   ; GdipDrawImageRectRect and disposed after.
   pBitmap2 := Gdip_CloneBitmap(pBitmap)

   DllCall("gdiplus.dll\GdipGetImageGraphicsContext", "Ptr",pBitmap, "PtrP",  pGraphics)
   DllCall("gdiplus.dll\GdipSetSmoothingMode", "Ptr",pGraphics, "Int",2)
   DllCall("gdiplus.dll\GdipSetInterpolationMode", "Ptr",pGraphics, "Int",7)
   DllCall("gdiplus.dll\GdipGraphicsClear", "Ptr",pGraphics, "Int",BG)
   DllCall("gdiplus\GdipCreateImageAttributes", "PtrP",pAttr)

   ; The transparency is applied here.
   DllCall("gdiplus\GdipSetImageAttributesColorMatrix", "Ptr",pAttr, "Int",1,    "Int",1, "Ptr",&CM, "Ptr",0, "Int",0)
   
   DllCall("gdiplus.dll\GdipGetImageWidth", "Ptr",pBitmap, "PtrP",CW)
   DllCall("gdiplus.dll\GdipGetImageHeight","Ptr",pBitmap, "PtrP",CH)
   
   DllCall("gdiplus\GdipDrawImageRectRect", "Ptr",pGraphics, "Ptr",pBitmap2, "Float",0, "Float",0, "Float",CW, "Float",CH,   "Float",  0, "Float",0, "Float",CW, "Float",CH, "Int",  UnitPixel:=2, "Ptr",   pAttr, "Ptr",0, "Ptr",0 ) 

   ; Dispose
   Gdip_DisposeImage(pBitmap2)
   DllCall("gdiplus\GdipDisposeImageAttributes", "Ptr",pAttr)
   DllCall("gdiplus.dll\GdipDeleteGraphics", "Ptr",pGraphics)

   return 
   
}
The image above with transparency just on the text would look like this:
Spoiler
When i move it above your avatar, i can see it thought the text.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDIp?

20 Jul 2021, 19:23

I understand now @c7aesa7r :thumbup:
Allow me sometime... I will reply.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 03:26

GdipSetImageAttributesRemapTable() seems the way to go.
..and when I searched for it, I see @swagfag had already suggested it.
https://www.autohotkey.com/boards/viewtopic.php?style=17&p=397853#p397853

Why don't you try @Xtra 's Gdip_FilterColor() ?

Code: Select all

DrawTXT(PBITMAP, "Hello World", 0xFFFFFFFF, TXThWnd)
Gdip_FilterColor(pBitmap, 0xFFFFFFFF, 0xB3FFFFFF)
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 06:31

SKAN wrote:
21 Jul 2021, 03:26
GdipSetImageAttributesRemapTable() seems the way to go.
..and when I searched for it, I see @swagfag had already suggested it.
https://www.autohotkey.com/boards/viewtopic.php?style=17&p=397853#p397853

Why don't you try @Xtra 's Gdip_FilterColor() ?

Code: Select all

DrawTXT(PBITMAP, "Hello World", 0xFFFFFFFF, TXThWnd)
Gdip_FilterColor(pBitmap, 0xFFFFFFFF, 0xB3FFFFFF)
Does it got transparent there? here it dont:
Spoiler
And if the image contains anywhere the same pixel color than what we used in the text it would also be replaced by Gdip_FilterColor(), don't?
User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 07:10

c7aesa7r wrote: Does it got transparent there?
It currently assumes 0xFF for the alpha channel, but it could be modified to allow that to be specified as well…
c7aesa7r wrote: And if the image contains anywhere the same pixel color than what we used in the text it would also be replaced by Gdip_FilterColor(), don't?
That is true, it would replace it everywhere it appears, so it may not be worth modifying Gdip_FilterColor() for your case.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 07:11

c7aesa7r wrote:
21 Jul 2021, 06:31
Does it got transparent there?
I won't use gdip.ahk.
Ask @Xtra if it supports alpha channel
c7aesa7r wrote:
21 Jul 2021, 06:31
And if the image contains anywhere the same pixel color than what we used in the text it would also be replaced by Gdip_FilterColor(), don't?
Replace the color before writing text.
 

Code: Select all

Gdip_FilterColor(pBitmap, 0xFFFFFFFF, 0xFFFEFEFE)
DrawTXT(PBITMAP, "Hello World", 0xFFFFFFFF, TXThWnd)
Gdip_FilterColor(pBitmap, 0xFFFFFFFF, 0xB3FFFFFF)
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 07:19

I won't use gdip.ahk.
I doesn't need to be gdip.ahk, it can be anything you are able to, my code is just a sketch no problem if i need to rewrite everything to achieve the goal of the topic.
User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 07:32

SKAN wrote: Ask @Xtra if it supports alpha channel
He shared the source code, and it hard codes 0xFF for the alpha channel, but that could be modified without too much trouble.
SKAN wrote: Replace the color before writing text.
Good idea. :thumbup: Or write the text in the slightly different color, then replace that color with the new alpha channel value when calling Gdip_FilterColor().
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 08:33

He shared the source code, and it hard codes 0xFF for the alpha channel, but that could be modified without too much trouble.
@boiler what do you use to convert the source to mcode? I have no idea whats mcode/gcc.
I was searching in the forum and found:
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4642.
I have downloaded tdm-gcc but I'm not sure what exe to use in the gcc compiler option of the script above.
Whatever exe i use it only generate the x86 code.
Searching more about this, to see if i manage how to convert that code and edit the alpha channel.
User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 08:38

When I compiled MCode, I used an online MCode compiler that is now a dead link (http://mcode-generator.com/), and I believe @Xtra used the same. The page you linked discusses the alternative, which I have not used but would also work. It's actually the more popular approach.
mcl
Posts: 355
Joined: 04 May 2018, 16:35

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 09:54

Sorry for jumping into conversation uninvited, but I have two thoughts that may be of use.
1. Default text rendering hint is 'SystemDefault', which is usually ClearType, and its subpixel precision looks very bad on transparent background.
It would be better to change 0 in the line with GdipSetTextRenderingHint to 3 − antialiased and hinted.
2. If drawed text needs to be transparent, one solution is to flip alpha channel, draw text with full alpha, and flip alpha channel back.
Tried that, didn't work: fully transparent pixels do not store color information anymore, and flipping back results in all black pixels.

UPD: the code below is very inefficient, but it works:
Spoiler
Last edited by mcl on 21 Jul 2021, 13:07, edited 1 time in total.
github://oGDIp - GDI+ wrapper for AHK v1.1
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 10:21

c7aesa7r wrote:
21 Jul 2021, 07:19
I doesn't need to be gdip.ahk, it can be anything you are able to, my code is just a sketch no problem if i need to rewrite everything to achieve the goal of the topic.
I re-wrote your example with calls to GdipSetImageAttributesRemapTable().
The written white text is too thin and gets blended with the bg color and hence there is no white color at all to be replaced.
User avatar
Xtra
Posts: 2744
Joined: 02 Oct 2015, 12:15

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 12:12

Code: Select all

Gdip_ConvertToTransparent(pBitmap, color := "0xFFFFFF")
{
	static ConvertTransparentMCode
	if (ConvertTransparentMCode = "")
	{
		if (A_PtrSize = 4) ; (32bit)
        {
            MCode := ""
			. "2,x86:VVdWU4tEJCCLTCQki2wkGI14A4XAD0n4i0QkHIHJAAAA"
			. "/8H/AoXAfkqF7X5Gi1wkFMHnAsHlAjH2jbQmAAAAAI0UK4nY6x"
			. "CJ9o28JwAAAACDwAQ50HQROwh19ccAAAAAAIPABDnQde+DxgEB"
			. "+zl0JBx1zVsxwF5fXcM="
        }
        else ; A_PtrSize = 8 (64bit)
        {
            mCode := ""
			. "2,x64:U0WNWQNFhclFD0nZRItMJDBBwfsCQYHJAAAA/0WFwH5Y"
			. "hdJ+VI1C/01j20Ux0knB4wJIjRyFBAAAAGYPH0QAAEiNFAtIic"
			. "jrEA8fgAAAAABIg8AESDnQdBREOwh18scAAAAAAEiDwARIOdB1"
			. "7EGDwgFMAdlFOdB1xzHAW8M="
        }
		ConvertTransparentMCode := MCode(mCode)
    }
	
    Gdip_GetImageDimensions(pBitmap, w, h)
	if !(w && h)
		return -1

	if (E1 := Gdip_LockBits(pBitmap, 0, 0, w, h, stride, scan, bitmapData))
		return -2
    
	E := DllCall(ConvertTransparentMCode, "uint", scan, "int", w, "int", h, "int", stride, "uint", color, "cdecl")
    
	Gdip_UnlockBits(pBitmap, bitmapData)
	
	return (E = "") ? -3 : E
}
Mcode:
Spoiler
These were all made over a year ago.
Give it a try HTH
c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: How to draw transparent text on a bitmap using GDIp?

21 Jul 2021, 13:16

Thank you XTRA, your code result in this image:
Spoiler
Looks like some white pixels did not got transparency.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: todd and 147 guests