pBrush := Gdip_BrushCreateSolid(Gdip_ToARGB(A, R, G, B))

GDI+ standard library 1.45 by tic

You can use the following to read from a BRA in AHK_L unicode, but the BRA library needs to be rewritten to be able to create BRAs, so AHK would need to be used to create BRAs for now
Gdip_BitmapFromBRA(ByRef BRAFromMemIn, File, Alternate=0) { BRAHeader := StrGet(&BRAFromMemIn, "CP0") if !BRAHeader return -1 Loop, Parse, BRAHeader, `n { if (A_Index = 1) { StringSplit, Header, A_LoopField, | if (Header0 != 4 || Header2 != "BRA!") return -2 } else if (A_Index = 2) { StringSplit, Info, A_LoopField, | if (Info0 != 3) return -3 } else break } if !Alternate StringReplace, File, File, \, \\, All RegExMatch(BRAHeader, "mi`n)^" (Alternate ? File "\|.+?\|(\d+)\|(\d+)" : "\d+\|" File "\|(\d+)\|(\d+)") "$", FileInfo) if !FileInfo return -4 hData := DllCall("GlobalAlloc", "uint", 2, "uptr", FileInfo2, "ptr") pData := DllCall("GlobalLock", "ptr", hData, "ptr") DllCall("RtlMoveMemory", "ptr", pData, "ptr", &BRAFromMemIn+Info2+FileInfo1, "uptr", FileInfo2) DllCall("GlobalUnlock", "ptr", hData) DllCall("ole32\CreateStreamOnHGlobal", "ptr", hData, "int", 1, "ptr*", pStream) DllCall("gdiplus\GdipCreateBitmapFromStream", "ptr", pStream, "ptr*", pBitmap) ObjRelease(pStream) return pBitmap }
A note is that you would need to use the *c option when reading the BRA
FileRead, BRA, *c Gdip.tutorial.file-fish.bra
Thanks to fincs for his help with this



Along the lines of filtering out pixels and such, you could take two images (probably of the same dimensions), and filter out pixels that are not the same.
For example, I have these screenshots from RuneScape:


Filtering out pixels that are not identical, I'd be left with the interface on the right, minus the mini-map and the compass, and the interface on the top left.
That's only an example, but I've found the need for such a function many times for other cases. I've just taken the easy road in using Photoshop, but...


WARNING: This is old post; continuation here.
Hi tic,
I wrapped some additional GraphicsPath GDI+ functions. Feel free to make them part of your Gdip.ahk library. I'm also posting an example which shows how to work with GraphicsPaths and hatch & linear gradient Brushes. Tested and works on AHK Basic and AHK_L.
Functions
;##################################################################################### ; GraphicsPath functions added by Learning one ;##################################################################################### ; Function Gdip_AddPathBeziers ; Description Adds a sequence of connected Bézier splines to the current figure of this path. ; ; pPath Pointer to the GraphicsPath ; Points the coordinates of all the points passed as x1,y1|x2,y2|x3,y3..... ; ; return status enumeration. 0 = success ; Notes The first spline is constructed from the first point through the fourth point in the array and uses the second and third points as control points. Each subsequent spline in the sequence needs exactly three more points: the ending point of the previous spline is used as the starting point, the next two points in the sequence are control points, and the third point is the ending point. Gdip_AddPathBeziers(pPath, Points) { StringSplit, Points, Points, | VarSetCapacity(PointF, 8*Points0) Loop, %Points0% { StringSplit, Coord, Points%A_Index%, `, NumPut(Coord1, PointF, 8*(A_Index-1), "float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "float") } return DllCall("gdiplus\GdipAddPathBeziers", "uint", pPath, "uint", &PointF, "int", Points0) } Gdip_AddPathBezier(pPath, x1, y1, x2, y2, x3, y3, x4, y4) { ; Adds a Bézier spline to the current figure of this path return DllCall("gdiplus\GdipAddPathBezier", "uint", pPath , "float", x1, "float", y1, "float", x2, "float", y2 , "float", x3, "float", y3, "float", x4, "float", y4) } ; Function Gdip_AddPathLines ; Description Adds a sequence of connected lines to the current figure of this path. ; ; pPath Pointer to the GraphicsPath ; Points the coordinates of all the points passed as x1,y1|x2,y2|x3,y3..... ; ; return status enumeration. 0 = success Gdip_AddPathLines(pPath, Points) { StringSplit, Points, Points, | VarSetCapacity(PointF, 8*Points0) Loop, %Points0% { StringSplit, Coord, Points%A_Index%, `, NumPut(Coord1, PointF, 8*(A_Index-1), "float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "float") } return DllCall("gdiplus\GdipAddPathLine2", "uint", pPath, "uint", &PointF, "int", Points0) } Gdip_AddPathLine(pPath, x1, y1, x2, y2) { return DllCall("gdiplus\GdipAddPathLine", "uint", pPath , "float", x1, "float", y1, "float", x2, "float", y2) } Gdip_AddPathArc(pPath, x, y, w, h, StartAngle, SweepAngle) { return DllCall("gdiplus\GdipAddPathArc", "uint", pPath, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle) } Gdip_AddPathPie(pPath, x, y, w, h, StartAngle, SweepAngle) { return DllCall("gdiplus\GdipAddPathPie", "uint", pPath, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle) } Gdip_StartPathFigure(pPath) { ; Starts a new figure without closing the current figure. Subsequent points added to this path are added to the new figure. return DllCall("gdiplus\GdipStartPathFigure", "uint", pPath) } Gdip_ClosePathFigure(pPath) { ; Closes the current figure of this path. return DllCall("gdiplus\GdipClosePathFigure", "uint", pPath) } ; Function Gdip_DrawPath ; Description draws a sequence of lines and curves defined by a GraphicsPath object ; ; pGraphics Pointer to the Graphics of a bitmap ; pPen Pointer to a pen ; pPath Pointer to a Path ; ; return status enumeration. 0 = success Gdip_DrawPath(pGraphics, pPen, pPath) { return DllCall("gdiplus\GdipDrawPath", "uint", pGraphics, "uint", pPen, "uint", pPath) } Gdip_WidenPath(pPath, pPen, Matrix=0, Flatness=1) { ; Replaces this path with curves that enclose the area that is filled when this path is drawn by a specified pen. This method also flattens the path. return DllCall("gdiplus\GdipWidenPath", "uint", pPath, "uint", pPen, "uint", Matrix, "float", Flatness) } Gdip_ClonePath(pPath) { DllCall("gdiplus\GdipClonePath", "uint", pPath, "uint*", pPathClone) return pPathClone }
Example
#NoEnv ;=== Create Gui, OnMessage === Gui 1: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs hGui := WinExist() Gui 1: Show, NA w := 550, h := 280 OnMessage(0x201, "WM_LBUTTONDOWN") ;===GDI+ prepare === pToken := Gdip_Startup() hbm := CreateDIBSection(w, h), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm) G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 4) ;=== Background === pBrush := Gdip_CreateLineBrushFromRect(0, 0, w, h, 0xff555555, 0xff050505) Gdip_FillRectangle(G, pBrush, 0, 0, w, h) Gdip_DeleteBrush(pBrush) pBrush := Gdip_BrushCreateHatch(0xff000000, 0x00000000, 8) Gdip_FillRectangle(G, pBrush, 0, 0, w, h) Gdip_DeleteBrush(pBrush) ;=== Create path (Bat) === pPath := Gdip_CreatePath() ; creates a Path (GraphicsPath object) Gdip_StartPathFigure(pPath) ; starts a new figure in this Path Gdip_AddPathLine(pPath, 110,95, 220,95) ; adds a line to the current figure of this path Gdip_AddPathBezier(pPath, 220,95, 228,112, 233,120, 262,120) ; adds bezier Gdip_AddPathLines(pPath, "262,120|265,95|269,110|280,110|284,95|287,120") ; adds lines Gdip_AddPathBezier(pPath, 287,120, 305,120, 320,120, 330,95) Gdip_AddPathLine(pPath, 330,95, 439,95) Gdip_AddPathBeziers(pPath, "439,95|406,108|381,126|389,159|322,157|287,170|275,206|262,170|227,157|160,159|168,126|144,109|110,95") ; adds beziers Gdip_ClosePathFigure(pPath) ; closes the current figure of this path ;=== Fill & draw path (Bat) === ; now when the path is finished, we can fill it with brushes and outline with pens ;pPen := Gdip_CreatePen(0x22ffffff, 14), Gdip_DrawPath(G, pPen, pPath), Gdip_DeletePen(pPen) ; uncomment to draw extra outline pBrush := Gdip_CreateLineBrushFromRect(0, 95, w, (h-190)/2, 0xff110000, 0xff664040) Gdip_FillPath(G, pBrush, pPath) ; fill Bat background 1 Gdip_DeleteBrush(pBrush) pBrush := Gdip_BrushCreateHatch(0xff000000, 0x00000000, 21) Gdip_FillPath(G, pBrush, pPath) ; fill Bat background 2 Gdip_DeleteBrush(pBrush) pPen := Gdip_CreatePen(0xffa5a5a5, 5) Gdip_DrawPath(G, pPen, pPath) ; draw Bat outline 1 Gdip_DeletePen(pPen) pPen := Gdip_CreatePen(0xff000000, 1) Gdip_DrawPath(G, pPen, pPath) ; draw Bat outline 2 Gdip_DeletePen(pPen) Gdip_DeletePath(pPath) ; delete the Path as it is no longer needed and wastes memory ;=== Update, Delete, Shutdown === UpdateLayeredWindow(hGui, hdc, (A_ScreenWidth-w)//2, (A_ScreenHeight-h)//2, w, h) SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc) Gdip_DeleteGraphics(G) Gdip_Shutdown(pToken) return Esc::ExitApp ;===Functions=========================================================================== #Include Gdip.ahk WM_LBUTTONDOWN() { PostMessage, 0xA1, 2 } ;##################################################################################### ; GraphicsPath functions added by Learning one ;##################################################################################### ; Function Gdip_AddPathBeziers ; Description Adds a sequence of connected Bézier splines to the current figure of this path. ; ; pPath Pointer to the GraphicsPath ; Points the coordinates of all the points passed as x1,y1|x2,y2|x3,y3..... ; ; return status enumeration. 0 = success ; Notes The first spline is constructed from the first point through the fourth point in the array and uses the second and third points as control points. Each subsequent spline in the sequence needs exactly three more points: the ending point of the previous spline is used as the starting point, the next two points in the sequence are control points, and the third point is the ending point. Gdip_AddPathBeziers(pPath, Points) { StringSplit, Points, Points, | VarSetCapacity(PointF, 8*Points0) Loop, %Points0% { StringSplit, Coord, Points%A_Index%, `, NumPut(Coord1, PointF, 8*(A_Index-1), "float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "float") } return DllCall("gdiplus\GdipAddPathBeziers", "uint", pPath, "uint", &PointF, "int", Points0) } Gdip_AddPathBezier(pPath, x1, y1, x2, y2, x3, y3, x4, y4) { ; Adds a Bézier spline to the current figure of this path return DllCall("gdiplus\GdipAddPathBezier", "uint", pPath , "float", x1, "float", y1, "float", x2, "float", y2 , "float", x3, "float", y3, "float", x4, "float", y4) } ; Function Gdip_AddPathLines ; Description Adds a sequence of connected lines to the current figure of this path. ; ; pPath Pointer to the GraphicsPath ; Points the coordinates of all the points passed as x1,y1|x2,y2|x3,y3..... ; ; return status enumeration. 0 = success Gdip_AddPathLines(pPath, Points) { StringSplit, Points, Points, | VarSetCapacity(PointF, 8*Points0) Loop, %Points0% { StringSplit, Coord, Points%A_Index%, `, NumPut(Coord1, PointF, 8*(A_Index-1), "float"), NumPut(Coord2, PointF, (8*(A_Index-1))+4, "float") } return DllCall("gdiplus\GdipAddPathLine2", "uint", pPath, "uint", &PointF, "int", Points0) } Gdip_AddPathLine(pPath, x1, y1, x2, y2) { return DllCall("gdiplus\GdipAddPathLine", "uint", pPath , "float", x1, "float", y1, "float", x2, "float", y2) } Gdip_AddPathArc(pPath, x, y, w, h, StartAngle, SweepAngle) { return DllCall("gdiplus\GdipAddPathArc", "uint", pPath, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle) } Gdip_AddPathPie(pPath, x, y, w, h, StartAngle, SweepAngle) { return DllCall("gdiplus\GdipAddPathPie", "uint", pPath, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle) } Gdip_StartPathFigure(pPath) { ; Starts a new figure without closing the current figure. Subsequent points added to this path are added to the new figure. return DllCall("gdiplus\GdipStartPathFigure", "uint", pPath) } Gdip_ClosePathFigure(pPath) { ; Closes the current figure of this path. return DllCall("gdiplus\GdipClosePathFigure", "uint", pPath) } ; Function Gdip_DrawPath ; Description draws a sequence of lines and curves defined by a GraphicsPath object ; ; pGraphics Pointer to the Graphics of a bitmap ; pPen Pointer to a pen ; pPath Pointer to a Path ; ; return status enumeration. 0 = success Gdip_DrawPath(pGraphics, pPen, pPath) { return DllCall("gdiplus\GdipDrawPath", "uint", pGraphics, "uint", pPen, "uint", pPath) } Gdip_WidenPath(pPath, pPen, Matrix=0, Flatness=1) { ; Replaces this path with curves that enclose the area that is filled when this path is drawn by a specified pen. This method also flattens the path. return DllCall("gdiplus\GdipWidenPath", "uint", pPath, "uint", pPen, "uint", Matrix, "float", Flatness) } Gdip_ClonePath(pPath) { DllCall("gdiplus\GdipClonePath", "uint", pPath, "uint*", pPathClone) return pPathClone }
Screenshot of example
EDIT 21.09.2012.: added: Gdip_WidenPath, Gdip_AddPathBezier, Gdip_ClonePath, updated example.

My Website • Recommended: AutoHotkey Unicode 32-bit • Join DropBox, Copy
I am trying my best to understand, but would really appreciate if someone could explain in simple terms for me.
What i am wanting to do is do an imagesearch of a printscreen
From this thread i see i can probably do it with Gdip.ahk, but i am struggling to work out how to use it.
Very basic idea
Print Screen active window, save as image.png Search this image with another saved image2.png
Does that make sensee?
Regards
Surreall

https://ahknet.autoh...ll/Gdip_All.ahk
Good job, butGdip_SaveBitmapToFile()
does not work when you run the script with AutoHotkey_L 64-bit Unicode and try to extract icon from exe.; Run the script with AutoHotkey_L 64-bit Unicode FullPath := A_AhkPath pToken := Gdip_Startup() pBitmap := Gdip_CreateBitmapFromFile(FullPath) ; (FullPath,1,48) doesn't help MsgBox % pBitmap ; returns -2 on 64-bit Gdip_SaveBitmapToFile(pBitmap, A_ScriptDir "\Gdiptest.png") Gdip_DisposeImage(pBitmap) Gdip_Shutdown(pToken) Run, % A_ScriptDir "\Gdiptest.png" ExitApp #Include Gdip_All.ahk
It looks like the problem is with the standard gdip library as well: that works with _L but not with basic.

I got it working okay on taking screenshots of windows, but when i use it to take a screenshot of a game window it returns a black image, but the window border is showing okay in the image.
Any ideas why i get a black inner?
Regards
Surreall
EDIT: Alt-Prntscreen grabs a pic fine, i am on windows 7 64 bit if that makes a difference

I'm not sure how the Alt+PrintScreen method does it without repainting, but it might be worth looking into that or just sending Alt+PrintScreen to the window.

That usually happens if the application uses owner draw and doesn't rely on WM_PAINT to perform painting.
I'm not sure how the Alt+PrintScreen method does it without repainting, but it might be worth looking into that or just sending Alt+PrintScreen to the window.
I tried sending Alt+printscreen, and that also doesnt work. (using controlsend) I get a 1 Kb file lol
Regards
Surreall

Did you try pasting into paint?
Yes, i got a this doesnt support this type of file error
Here is the code
pToken := Gdip_Startup() pBitmap := Gdip_BitmapFromHWND(WinExist("Game Window")) ; hwnd = name of window, eg pBitmapNotepad := Gdip_BitmapFromHWND(WinExist("Notepad")) MsgBox % pBitmap Gdip_SaveBitmapToFile(pBitmap, A_ScriptDir "\Gdiptest.png") Gdip_DisposeImage(pBitmap) Gdip_Shutdown(pToken) Run, % A_ScriptDir "\Gdiptest.png" ExitApp

Hey all,
I got it working okay on taking screenshots of windows, but when i use it to take a screenshot of a game window it returns a black image, but the window border is showing okay in the image.
some games just dont allow you to do it, it sucks

Here is the code
pBitmap := Gdip_BitmapFromHWND(WinExist("Game Window"))
Don't use Gdip_BitmapFromHWND. That will try and raise WM_PAINT. Use Gdip_BitmapFromScreen
Gdip_BitmapFromScreen("hwnd:" WinExist("Game Window"))
Learning one
Awesome! I'll definitely try and release an update soon
