Ok, as pointed out (with my tiny error

) here is the updated function to allow screenshots of chosen monitor:
This is correct, ignore "Guest's" comments. The only slight caveat is that if a window is between 2 monitors that each have different resolutions (and input var is "window"), then each respective part of the window will be the resolution of the monitor it is on. I do not wish to fix this as it is unimportant to me, unless someone desperately wants it
Code:
; TextToImage v1.08 by tic
;
; TextToImage can overlay writing to a screenshot of the entire screen or active window, or from an existing image and write to file
; TextToImage(In, Text, Output, x, y, Font, TColour, Size, Weight)
;
; In: Can either be the "Screen" or "Window" and will take a screenshot of the respective choice, or the location of an exisitng image
; Screen will use all available monitors, and "screen1" will use monitor 1, "screen2", moniotr 2, etc.
;
; Text: This is the text to overlay onto the screenshot
;
; Output: This is the path and filename that the image will be written to.
; The extension can be .bmp,.jpg,.png,.tif,.gif and will be written as that type accordingly
;
; x: This is the x-coordinate to place the text. This coordinate will be the distance from the left the text will be placed.
; This value may be a ratio. For instance 4:5 would place the text at the position 4/5ths of the width of the image
; You must also consult which mode align is in
;
; y: This is the y-coordinate to place the text. This coordinate will be the distance from the top the text will be placed.
; This value may be a ratio. For instance 1:3 would place the text at the position 1/3ths of the height of the image
; You must also consult which mode align is in
;
; Size: This is the height of the text in pixels
;
; Align: This must have 2 styles set, The text's x placement (Left,Centre,Right) and the text's y placement (Top,Bottom)
; It must be used for example as Left|Bottom - This would place the text at the bottom of it's bounding area and aligned left
;
; Weight: This is the boldness of the text. Make the value greater to make it more bold
;
; Font: This is the font to set the text to be
; Examples are: Arial, Bookman Old Style, Times New Roman
;
; TColour: This is the colour to set the text in RGB format.
; So FF0000 is red
;
; Style: Can contain the words Underline,Italic,Strikeout and will set the text in the appropriate styles
TextToImage(In="Screen", Text="TextToImage", Output="TextToImage.bmp", x="1:2", y="1:2", Size="20", Align="Bottom|Centre", Weight="400", Font="Arial", TColour="000000", Style="")
{
hGdiPlus := DllCall("LoadLibrary", "Str", "gdiplus.dll")
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UIntP", pToken, "UInt", &si, "UInt", 0)
If In Contains Screen,Window
{
If (In = "Screen")
{
SysGet, nL, 76 ; Get coordinates for all monitors
SysGet, nT, 77
SysGet, nW, 78
SysGet, nH, 79
}
Else If ((SubStr(In, 1, 6) = "Screen") && ((Substr(In, 0) & 1) != ""))
{
SysGet, Coords, Monitor, % Substr(In, 0) ;%
nL := CoordsLeft, nT := CoordsTop, nW := CoordsRight - CoordsLeft, nH := CoordsBottom - CoordsTop
}
Else If (In = "Window")
{
WinGetPos, nL, nT, nW, nH, A ; Get coordinates for active window
WinGet, ID, ID, A
WinGetTitle, Title, A
Winget, MinMax, MinMax, A
If !(DllCall("IsWindowVisible", UInt, ID) && (Title) && (MinMax != -1)) ; Check active window is visible
{
GoSub, TTS_GdiplusShutdown
Return, "Window is not visible"
}
}
mDC := DllCall("CreateCompatibleDC", "UInt", 0)
NumPut(VarSetCapacity(bi, 40, 0), bi)
NumPut(nW, bi, 4)
NumPut(nH, bi, 8)
NumPut(32, NumPut(1, bi, 12, "UShort"), 0, "UShort")
hBM := DllCall("gdi32\CreateDIBSection", "UInt", mDC, "UInt", &bi, "UInt", 0, "UIntP", "", "UInt", 0, "UInt", 0)
oBM := DllCall("SelectObject", "UInt", mDC, "UInt", hBM) ; Place bitmap object Into compatible DC
hDC := DllCall("GetDC", "UInt", 0) ; Get DC of screen and bitblt
DllCall("BitBlt", "UInt", mDC
, "Int", 0, "Int", 0
, "Int", nW, "Int", nH
, "UInt", hDC, "Int"
, nL, "Int", nT
, "UInt", 0x40000000|0x00CC0020)
}
Else
{
VarSetCapacity(wFile, StrLen(In)*2+2)
DllCall("kernel32\MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &In, "Int", -1, "UInt", &wFile, "Int", VarSetCapacity(wFile)//2)
DllCall("gdiplus\GdipCreateBitmapFromFile", "UInt", &wFile, "UIntP", pBitmap)
If !pBitmap
{
Gosub, TTS_GdiplusShutdown
Return, "Failed to load image"
}
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "UInt", pBitmap, "UIntP", hBM, "UInt", 0)
DllCall("gdiplus\GdipDisposeImage", "Uint", pBitmap)
mDC := DllCall("CreateCompatibleDC", "UInt", 0)
oBM := DllCall("SelectObject", "UInt", mDC, "UInt", hBM)
hDC := DllCall("GetDC", "UInt", 0)
}
StringSplit, OutputArray, Output, .
Extension := "." . OutputArray%OutputArray0%
If Extension not in .bmp,.jpg,.png,.tif,.gif ; Check file extension is correct
{
GoSub, TTS_GdiplusShutdown
Return, "Invalid file extension. Only bmp,jpg,png,tif,gif are available"
}
VarSetCapacity(bm, 24, 0)
If !DllCall("GetObject", "UInt", hBM, "Int", 24, "UInt", &bm)
{
GoSub, TTS_GdiplusShutdown
Return, "GetObject failed on bitmap {" hBM "}"
}
Width := NumGet(bm, 4, "Int") ; Get properties of bitmap
Height := NumGet(bm, 8, "Int")
bpp := NumGet(bm, 18, "Ushort")
DllCall("SetBkMode", "UInt", mDC, "UInt", 1) ; Leave background untouched for background mix mode
DllCall("SetGraphicsMode", "UInt", mDC, "UInt", 2) ; Set graphics mode for DC to allow world transformations
VarSetCapacity(logfont, 60, 0)
LogPixelsSY := DllCall("GetDeviceCaps", "UInt", hDC, "Int", 90) ; Number of pixels per logical inch along the screen height
DllCall("ReleaseDC", "UInt", 0, "UInt", hDC)
TextHeight := -(Size*logPixelsSY)/72
NumPut(TextHeight, logfont, 0) ; Set text height
;NumPut(TextWidth, logfont, 4) ; Change text width
NumPut(Weight, logfont, 16) ; Set text weight
If InStr(Style, "Underline") ; Set style to be either underline,italic,Strikeout
NumPut(1, logfont, 21)
If InStr(Style, "Italic")
NumPut(1, logfont, 20)
If InStr(Style, "Strikeout")
NumPut(1, logfont, 22)
NumPut(5, logfont, 26) ; ClearType antialiasing XP and above only
AlignWord := "Right,Top,Bottom,Centre,Left"
AlignNum := "2,0,8,6,0"
StringSplit, AlignWords, AlignWord, `,
StringSplit, AlignNums, AlignNum, `,
Loop, %AlignWords0%
StringReplace, Align, Align, % AlignWords%A_Index%, % AlignNums%A_Index%, All
StringSplit, Pos, Align, |
Align := Pos1 | Pos2
StringLeft, FaceName, Font, 32
DllCall("lStrcpy", "UInt", &logfont + 28, "Str", FaceName) ; Set font
DllCall("SetTextAlign", "UInt", mDC, "UInt", Align) ; Align text
#hFont := DllCall("CreateFontIndirect", "UInt", &logfont)
#hOldFont := DllCall("SelectObject", "UInt", mDC, "UInt", #hFont) ; Change DC Font
TColour := "0x" . TColour
prevColor := DllCall("SetTextColor", "UInt", mDC, "UInt", ((TColour & 0xFF) << 16) + (TColour & 0xFF00) + ((TColour >> 16) & 0xFF), "UInt")
If InStr(x, ":")
{
StringSplit, XRatio, x, :
XPos := XRatio1*(Width//XRatio2)
}
Else
XPos := x
If InStr(y, ":") ; Get ratios of x and y position
{
StringSplit, YRatio, y, :
YPos := YRatio1*(Height//YRatio2)
}
Else
YPos := y
StringSplit, Text, Text, `n
Loop, %Text0%
{
DllCall("TextOut", "UInt", mDC, "Int", XPos, "Int", YPos, "Str", Text%A_Index%, "UInt", StrLen(Text%A_Index%))
YPos += 1.5*Size ; Draw text Into device
}
DllCall("SelectObject", "UInt", mDC, "UInt", #hOldFont)
DllCall("DeleteObject", "UInt", #hFont) ; Restore DC Font
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UInt", hBM, "UInt", 0, "UIntP", pImage)
DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
DllCall("DeleteObject", "Uint", hBM)
DllCall("DeleteDC", "Uint", mDC)
DllCall("gdiplus\GdipGetImageEncodersSize", "UIntP", nCount, "UIntP", nSize) ; Get encoder
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "UInt", nCount, "UInt", nSize, "UInt", &ci)
Loop, %nCount%
{
nSize := DllCall("WideCharToMultiByte", "UInt", 0, "UInt", 0, "UInt", NumGet(ci, 76 * (A_Index - 1) + 44), "Int", -1, "UInt", 0, "Int", 0, "UInt", 0, "UInt", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte", "UInt", 0, "UInt", 0, "UInt", NumGet(ci, 76 * (A_Index - 1) + 44), "Int", -1, "Str", sString, "Int", nSize, "UInt", 0, "UInt", 0)
If !InStr(sString, Extension) ; Find encoder matching extension
Continue
pCodec := &ci + 76 * (A_Index - 1)
Break
}
If pImage ; Save image to file
{
sString := Output
nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sString, "Int", -1, "UInt", 0, "Int", 0)
VarSetCapacity(wString, nSize * 2)
DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sString, "Int", -1, "UInt", &wString, "Int", nSize)
DllCall("gdiplus\GdipSaveImageToFile", "UInt", pImage, "UInt", &wString, "UInt", pCodec, "UInt", 0)
DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)
}
GoSub, TTS_GdiplusShutdown
Return, XPos . "|" . YPos
TTS_GdiplusShutdown:
DllCall("gdiplus\GdiplusShutdown" , "UInt", pToken) ; Shutdown and free library
DllCall("FreeLibrary", "UInt", hGdiPlus)
Return
}
Edit: previous posts removed. hope a mod deletes them so as not to ruin the usefulness of this thread.