This function will add a text box to an image.
It has a ton of options about the look and position of the text box. The basics of the options are in the comments.
A file name can be specified for the source image and where to save the modified image. If no file is specified for the source or destination then the clipboard is used as the source or destination of the bitmap.
Code: Select all
; [Function] Image_TextBox
; Fanatic Guru
; 2018 11 11
;
; Function to use Gdip to add text to image
;
;{-----------------------------------------------
;
; Image_TextBox(Text, FilePath, SavePath, Options*)
;
; Parameters:
; Text text to add to image
; FilePath path to source file, blank to use image on Clipboard
; SavePath path to save modified image, blank to save modified image to Clipboard
; Options* variadic parameter for pseudo named paramater options
; For each named parameter use the format "Name=value"
; FontSize text font size (default "FontSize=24")
; Font text font name (default "Font=Arial")
; Style text font style; Regular|Bold|Italic|BoldItalic|Underline|Strikeout (default "Style=Regular")
; Align alignment of text; Near|Left|Centre|Center|Far|Right and Top|Up|Bottom|Down|vCentre|vCenter (default "Align=Center vCenter")
; Margin clear space between border and text boundary (default "Margin=0")
; TextColor color of text with alpha transparant, hex aarrggbb (default "TextColor=ffffffff" solid white)
; BoxColor color of box fill with alpha transparent, hex aarrggbb (default "BoxColor=ff000000" solid black)
; BorderColor color of border with alpha transparent, hex aarrggbb (default "BorderColor=ffff0000" solid red)
; Weight weight or thickness of border, 0 weight is no border (default "Weight=2")
; Render rendering hint; (default "Render=0")
; 0: SystemDefault, 1: SingleBitPerPixelGridFit, 2: SingleBitPerPixel, 3: AntiAliasGridFit, 4: AntiAlias, 5: ClearTypeGridFit
; Pos position of box; Left|Right|Top|Botton|vCenter or XY in format "x,y" or percentage in format ".x,.y";
; negative amounts goes from right or bottom (default "Pos=Bottom Left")
; examples "Pos=vCenter" vertical center or "Pos=100,200" 100 x 200 y or
; "Pos=.1,.2" 10% x 20% y or "Pos=-20,-.10" 20 x from right, 10% y from bottom
; Quality quality for images with compression format (default "Quality=75")
; BoxSize size of box in format "x,y" or "" to autofit (default "BoxSize=Auto")
;
; Notes: text will word wrap within box and `n can be used for new line
;
; Example:
; Image_TextBox("Example Text","Image_Test.PNG",, "FontSize=48", "Weight=6", "Margin=10", "Style=Bold", "Align=Right vCenter", "BoxSize=200,100", "Pos=-20,-.20", "BoxColor=55000000", "Render=5")
;
Image_TextBox(Text:="", FilePath:="", SavePath:="", Options*)
{
; Default Options
FontSize:=24, Font:="Arial", Style:="Regular", Align:="Center vCenter", Margin:=0, TextColor:="ffffffff", BoxColor:="ff000000", BorderColor:="ffff0000", Weight:="2", Render:=0, Pos:="Bottom Left", Quality:=75, BoxSize:="Auto"
; Options as Named Parameters
for key, Option in Options
{
Opt := StrSplit(Option, "=")
var := Opt.1, val := Opt.2
%var% := val
}
; Startup Gdip
if !pToken
{
If !pToken := Gdip_Startup()
{
MsgBox, 48, Gdip+ Error!, Gdip+ failed to start. Please ensure you have Gdip+ on your system.
ExitApp
}
else
{
OnExit, Exit_Image_TextBox
If !Gdip_FontFamilyCreate(Font)
{
MsgBox, 48, Font Error!, The font you have specified does not exist on the system.
ExitApp
}
}
}
; Get Bitmap, Graphics, Pen, and Brush
if FilePath
pBitmapFile := Gdip_CreateBitmapFromFile(FilePath)
else
pBitmapFile := Gdip_CreateBitmapFromClipboard()
pG := Gdip_GraphicsFromImage(pBitmapFile)
Gdip_SetSmoothingMode(pG, 4)
pPen := Gdip_CreatePen("0x" BorderColor, Weight)
pBrush := Gdip_BrushCreateSolid("0x" BoxColor)
; Get Width and Height of components
Width := Gdip_GetImageWidth(pBitmapFile)
Height := Gdip_GetImageHeight(pBitmapFile)
if (!BoxSize or BoxSize="Auto")
{
Options := "c" TextColor " s" FontSize " r" Render " " Style " " Align
Measure := StrSplit(Gdip_TextToGraphics(pG, Text, Options, Font,,,true), "|")
Box_Width := Measure.3 + (Weight * 2) + (Margin * 2)
Box_Height := Measure.4 + (Weight * 2) + (Margin * 2)
}
else
{
XY := StrSplit(BoxSize, ",")
Box_Width := XY.1, Box_Height := XY.2
}
; Process Number Box Position Options
if InStr(Pos, ",")
{
XY := StrSplit(Pos, ",")
if (0 < XY.1 and XY.1 < 1)
Box_X := Width * XY.1
else if (-1 < XY.1 and XY.1 < 0)
Box_X := Width + (Width * XY.1) - Box_Width - 1
else if (XY.1 < 0)
Box_X := Width + XY.1 - Box_Width - 1
else
Box_X := XY.1
if (0 < XY.2 and XY.2 < 1)
Box_Y := Height * XY.2
else if (-1 < XY.2 and XY.2 < 0)
Box_Y := Height + (Height * XY.2) - Box_Height - 1
else if (XY.2 < 0)
Box_Y := Height + XY.2 - Box_Height - 1
else
Box_Y := XY.2
Pos := XY.3
}
; Process Word Box Position Options
if InStr(Pos, "Left")
Box_X := 0
else if InStr(Pos, "Right")
Box_X := Width - Box_Width - 1
else if (Pos ~= "(?<!v)Center")
Box_X := (Width - Box_Width) / 2 - 1
if InStr(Pos, "Bottom")
Box_Y := Height - Box_Height - 1
else if InStr(Pos, "Top")
Box_Y := 0
else if InStr(Pos, "vCenter")
Box_Y := (Height - Box_Height) / 2 - 1
Border_X := Box_X + Weight / 2, Border_Y := Box_Y + Weight / 2
Border_Width := Box_Width - Weight, Border_Height := Box_Height - Weight
; Text X, Y, Width, Height
Padding := Margin + Weight
Text_X := Box_X + Padding - 1, Text_Y := Box_Y + Padding - 1
Text_Width := Box_Width - (Padding * 2), Text_Height := Box_Height - (Padding * 2)
; Draw Box, Border, and Text
Gdip_FillRectangle(pG, pBrush, Box_X, Box_Y, Box_Width, Box_Height)
if Weight
Gdip_DrawRectangle(pG, pPen, Border_X, Border_Y, Border_Width, Border_Height)
Options := "c" TextColor " s" FontSize " r" Render " " Style " " Align " x" Text_X " y" Text_Y
Gdip_TextToGraphics(pG, Text, Options, Font, Text_Width, Text_Height)
; Process Result
if SavePath
Gdip_SaveBitmapToFile(pBitmapFile, SavePath, Quality)
else
Gdip_SetBitmapToClipboard(pBitmapFile)
; Destroy Pen, Brush, Bitmap, and Graphic
Gdip_DeletePen(pPen)
Gdip_DeleteBrush(pBrush)
Gdip_DisposeImage(pBitmapFile)
Gdip_DeleteGraphics(pG)
return
; On Exit, make sure all Pointers Destroyed and Gdip Shutdown
Exit_Image_TextBox:
Gdip_DeletePen(pPen)
Gdip_DeleteBrush(pBrush)
Gdip_DisposeImage(pBitmapFile)
Gdip_DeleteGraphics(pG)
Gdip_Shutdown(pToken)
ExitApp
return
}
; }
Code: Select all
#Include [Function] Image_TextBox.ahk
F1::
send !{PrintScreen} ; get an image of current window on the clipboard for testing
Sleep 500
Comment = Default Bottom Left`nSize to Fit`nCenter Text
Image_TextBox(Comment)
DisplayClipboardInGui()
return
F2::
send !{PrintScreen} ; get an image of current window on the clipboard for testing
Sleep 500
Comment = Bigger Font with Style`nPostion 30 from Left`n150 from Bottom
Image_TextBox(Comment,,, "FontSize=36", "Weight=6", "Margin=10", "Style=Bold", "Pos=30,-150")
DisplayClipboardInGui()
return
F3::
send !{PrintScreen} ; get an image of current window on the clipboard for testing
Sleep 500
Comment = Bigger Font with Style`nText Aligned Right with Vertical Center Text Wrap`nSpecific Box Size`nPostion 15`% from Right`n10`% from Top`nColor Fill with Transparent
Image_TextBox(Comment,,, "FontSize=36", "Weight=6", "Margin=10", "Style=Bold", "Align=Right vCenter", "BoxSize=515,400", "Pos=-.15,.10", "BoxColor=55ff0000", "Render=5")
DisplayClipboardInGui()
return
; display modified image on clipboard in GUI
DisplayClipboardInGui()
{
static
Gui, Destroy
if DllCall("OpenClipboard", "uint", 0) {
if DllCall("IsClipboardFormatAvailable", "uint", 8) {
hBitmap := DllCall("GetClipboardData", "uint", 2)
}
DllCall("CloseClipboard")
}
Gui, Add, Pic, vPic, % "HBITMAP:*" hBitmap
Gui, Show
}
Esc::ExitApp
Hit F1, F2, or F3 to take a snapshot of the current window, add text and display in a gui. It is best to take a snapshot of a window that is smaller and not maximized. This is just so people can test the function without having to specify image files.
Also this function shows a pseudo-named parameter technique that might be useful to others for functions that have lots of options.
FG