[Function] Image_TextBox

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
FanaticGuru
Posts: 1907
Joined: 30 Sep 2013, 22:25

[Function] Image_TextBox

14 Dec 2018, 15:18

[Function] Image_TextBox

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
}
; }
Here is some example code:

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
This uses the clipboard and a Gui for testing.
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
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

Re: [Function] Image_TextBox

17 Dec 2018, 07:34

That's just a dope example dude. Thanks, I never knew i needed this until now.... :salute: :cookie:
live ? long & prosper : regards

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: Google [Bot] and 67 guests