매크로

조회 수 2834 추천 0 댓글 11

;클립보드에 있는 이미지를 불러와 비교하여 서치하는 방식이라 프린트스크린과 같이 사용해야 합니다.


F1::
image=서치할 이미지.png


pToken := Gdip_Startup()
pBitmapHayStack:=Gdip_CreateBitmapFromClipboard() ;현재 클립보드에 존재하는 이미지를 가져온다
pBitmapNeedle := Gdip_CreateBitmapFromFile(image)
Gdip_SaveBitmapToFile(pBitmapHayStack, "클립보드에 있는 이미지.png")? ;클립보드에 있는 이미지를 추출하여 저장한다
Gdip_SaveBitmapToFile(pBitmapNeedle, "서치할 이미지2.png") ;서치할 이미지를 추출하여 저장한다


if !Gdip_ImageSearch(pBitmapHayStack, pBitmapNeedle, x, y) ;클립보드에 있는 이미지와 서치할 이미지를 비교한다

?????? MsgBox, %x% %y% ;좌표값 출력


Gdip_DisposeImage(pBitmapHayStack), Gdip_DisposeImage(pBitmapNeedle)
Gdip_Shutdown(pToken)
exitapp





;Gdip.ahk



; Gdip standard library v1.45 by tic (Tariq Porter) 07/09/11
;
;#####################################################################################
;#####################################################################################
; STATUS ENUMERATION
; Return values for functions specified to have status enumerated return type
;#####################################################################################
;
; Ok =??????= 0
; GenericError????= 1
; InvalidParameter???= 2
; OutOfMemory????= 3
; ObjectBusy????= 4
; InsufficientBuffer??= 5
; NotImplemented???= 6
; Win32Error????= 7
; WrongState????= 8
; Aborted?????= 9
; FileNotFound????= 10
; ValueOverflow????= 11
; AccessDenied????= 12
; UnknownImageFormat??= 13
; FontFamilyNotFound??= 14
; FontStyleNotFound???= 15
; NotTrueTypeFont???= 16
; UnsupportedGdiplusVersion?= 17
; GdiplusNotInitialized??= 18
; PropertyNotFound???= 19
; PropertyNotSupported??= 20
; ProfileNotFound???= 21
;
;#####################################################################################
;#####################################################################################
; FUNCTIONS
;#####################################################################################
;
; UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
; BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster="")
; StretchBlt(dDC, dx, dy, dw, dh, sDC, sx, sy, sw, sh, Raster="")
; SetImage(hwnd, hBitmap)
; Gdip_BitmapFromScreen(Screen=0, Raster="")
; CreateRectF(ByRef RectF, x, y, w, h)
; CreateSizeF(ByRef SizeF, w, h)
; CreateDIBSection
;
;#####################################################################################

; Function:???? ???UpdateLayeredWindow
; Description:? ???Updates a layered window with the handle to the DC of a gdi bitmap
;
; hwnd??????? ????Handle of the layered window to update
; hdc?????????? ???Handle to the DC of the GDI bitmap to update the window with
; Layeredx????? ???x position to place the window
; Layeredy????? ???y position to place the window
; Layeredw????? ???Width of the window
; Layeredh????? ???Height of the window
; Alpha???????? ???Default = 255 : The transparency (0-255) to set the window transparency
;
; return????? ????If the function succeeds, the return value is nonzero
;
; notes??????If x or y omitted, then layered window will use its current coordinates
;???????If w or h omitted then current width and height will be used

UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)
{
?if ((x != "") && (y != ""))
??VarSetCapacity(pt, 8), NumPut(x, pt, 0), NumPut(y, pt, 4)

?if (w = "") ||(h = "")
??WinGetPos,,, w, h, ahk_id %hwnd%
??
?return DllCall("UpdateLayeredWindow", "uint", hwnd, "uint", 0, "uint", ((x = "") && (y = "")) ? 0 : &pt
?, "int64*", w|h<<32, "uint", hdc, "int64*", 0, "uint", 0, "uint*", Alpha<<16|1<<24, "uint", 2)
}

;#####################################################################################

; Function????BitBlt
; Description???The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle
;??????of pixels from the specified source device context into a destination device context.
;
; dDC?????handle to destination DC
; dx?????x-coord of destination upper-left corner
; dy?????y-coord of destination upper-left corner
; dw?????width of the area to copy
; dh?????height of the area to copy
; sDC?????handle to source DC
; sx?????x-coordinate of source upper-left corner
; sy?????y-coordinate of source upper-left corner
; Raster????raster operation code
;
; return????If the function succeeds, the return value is nonzero
;
; notes?????If no raster operation is specified, then SRCCOPY is used, which copies the source directly to the destination rectangle
;
; BLACKNESS????= 0x00000042
; NOTSRCERASE???= 0x001100A6
; NOTSRCCOPY???= 0x00330008
; SRCERASE????= 0x00440328
; DSTINVERT????= 0x00550009
; PATINVERT????= 0x005A0049
; SRCINVERT????= 0x00660046
; SRCAND????= 0x008800C6
; MERGEPAINT???= 0x00BB0226
; MERGECOPY????= 0x00C000CA
; SRCCOPY????= 0x00CC0020
; SRCPAINT????= 0x00EE0086
; PATCOPY????= 0x00F00021
; PATPAINT????= 0x00FB0A09
; WHITENESS????= 0x00FF0062
; CAPTUREBLT???= 0x40000000
; NOMIRRORBITMAP??= 0x80000000

BitBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, Raster="")
{
?return DllCall("gdi32\BitBlt", "uint", dDC, "int", dx, "int", dy, "int", dw, "int", dh
?, "uint", sDC, "int", sx, "int", sy, "uint", Raster ? Raster : 0x00CC0020)
}

;#####################################################################################

; Function????StretchBlt
; Description???The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle,
;??????stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary.
;??????The system stretches or compresses the bitmap according to the stretching mode currently set in the destination device context.
;
; ddc?????handle to destination DC
; dx?????x-coord of destination upper-left corner
; dy?????y-coord of destination upper-left corner
; dw?????width of destination rectangle
; dh?????height of destination rectangle
; sdc?????handle to source DC
; sx?????x-coordinate of source upper-left corner
; sy?????y-coordinate of source upper-left corner
; sw?????width of source rectangle
; sh?????height of source rectangle
; Raster????raster operation code
;
; return????If the function succeeds, the return value is nonzero
;
; notes?????If no raster operation is specified, then SRCCOPY is used. It uses the same raster operations as BitBlt??

StretchBlt(ddc, dx, dy, dw, dh, sdc, sx, sy, sw, sh, Raster="")
{
?return DllCall("gdi32\StretchBlt", "uint", ddc, "int", dx, "int", dy, "int", dw, "int", dh
?, "uint", sdc, "int", sx, "int", sy, "int", sw, "int", sh, "uint", Raster ? Raster : 0x00CC0020)
}

;#####################################################################################

; Function????SetStretchBltMode
; Description???The SetStretchBltMode function sets the bitmap stretching mode in the specified device context
;
; hdc?????handle to the DC
; iStretchMode???The stretching mode, describing how the target will be stretched
;
; return????If the function succeeds, the return value is the previous stretching mode. If it fails it will return 0
;
; STRETCH_ANDSCANS ??= 0x01
; STRETCH_ORSCANS ??= 0x02
; STRETCH_DELETESCANS ?= 0x03
; STRETCH_HALFTONE ??= 0x04

SetStretchBltMode(hdc, iStretchMode=4)
{
?return DllCall("gdi32\SetStretchBltMode", "uint", hdc, "int", iStretchMode)
}

;#####################################################################################

; Function????SetImage
; Description???Associates a new image with a static control
;
; hwnd?????handle of the control to update
; hBitmap????a gdi bitmap to associate the static control with
;
; return????If the function succeeds, the return value is nonzero

SetImage(hwnd, hBitmap)
{
?SendMessage, 0x172, 0x0, hBitmap,, ahk_id %hwnd%
?E := ErrorLevel
?DeleteObject(E)
?return E
}

;#####################################################################################

; Function????SetSysColorToControl
; Description???Sets a solid colour to a control
;
; hwnd?????handle of the control to update
; SysColor????A system colour to set to the control
;
; return????If the function succeeds, the return value is zero
;
; notes?????A control must have the 0xE style set to it so it is recognised as a bitmap
;??????By default SysColor=15 is used which is COLOR_3DFACE. This is the standard background for a control
;
; COLOR_3DDKSHADOW????= 21
; COLOR_3DFACE?????= 15
; COLOR_3DHIGHLIGHT????= 20
; COLOR_3DHILIGHT????= 20
; COLOR_3DLIGHT?????= 22
; COLOR_3DSHADOW????= 16
; COLOR_ACTIVEBORDER???= 10
; COLOR_ACTIVECAPTION???= 2
; COLOR_APPWORKSPACE???= 12
; COLOR_BACKGROUND????= 1
; COLOR_BTNFACE?????= 15
; COLOR_BTNHIGHLIGHT???= 20
; COLOR_BTNHILIGHT????= 20
; COLOR_BTNSHADOW????= 16
; COLOR_BTNTEXT?????= 18
; COLOR_CAPTIONTEXT????= 9
; COLOR_DESKTOP?????= 1
; COLOR_GRADIENTACTIVECAPTION?= 27
; COLOR_GRADIENTINACTIVECAPTION?= 28
; COLOR_GRAYTEXT????= 17
; COLOR_HIGHLIGHT????= 13
; COLOR_HIGHLIGHTTEXT???= 14
; COLOR_HOTLIGHT????= 26
; COLOR_INACTIVEBORDER???= 11
; COLOR_INACTIVECAPTION???= 3
; COLOR_INACTIVECAPTIONTEXT??= 19
; COLOR_INFOBK?????= 24
; COLOR_INFOTEXT????= 23
; COLOR_MENU?????= 4
; COLOR_MENUHILIGHT????= 29
; COLOR_MENUBAR?????= 30
; COLOR_MENUTEXT????= 7
; COLOR_SCROLLBAR????= 0
; COLOR_WINDOW?????= 5
; COLOR_WINDOWFRAME????= 6
; COLOR_WINDOWTEXT????= 8

SetSysColorToControl(hwnd, SysColor=15)
{
?? WinGetPos,,, w, h, ahk_id %hwnd%
?? bc := DllCall("GetSysColor", "Int", SysColor)
?? pBrushClear := Gdip_BrushCreateSolid(0xff000000 | (bc >> 16 | bc & 0xff00 | (bc & 0xff) << 16))
?? pBitmap := Gdip_CreateBitmap(w, h), G := Gdip_GraphicsFromImage(pBitmap)
?? Gdip_FillRectangle(G, pBrushClear, 0, 0, w, h)
?? hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
?? SetImage(hwnd, hBitmap)
?? Gdip_DeleteBrush(pBrushClear)
?? Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap), DeleteObject(hBitmap)
?? return 0
}

;#####################################################################################

; Function????Gdip_BitmapFromScreen
; Description???Gets a gdi+ bitmap from the screen
;
; Screen????0 = All screens
;??????Any numerical value = Just that screen
;??????x|y|w|h = Take specific coordinates with a width and height
; Raster????raster operation code
;
; return????? ???If the function succeeds, the return value is a pointer to a gdi+ bitmap
;??????-1:??one or more of x,y,w,h not passed properly
;
; notes?????If no raster operation is specified, then SRCCOPY is used to the returned bitmap

Gdip_BitmapFromScreen(Screen=0, Raster="")
{
?if (Screen = 0)
?{
??Sysget, x, 76
??Sysget, y, 77?
??Sysget, w, 78
??Sysget, h, 79
?}
?else if (SubStr(Screen, 1, 5) = "hwnd:")
?{
??Screen := SubStr(Screen, 6)
??if !WinExist( "ahk_id " Screen)
???return -2
??WinGetPos,,, w, h, ahk_id %Screen%
??x := y := 0
??hhdc := GetDCEx(Screen, 3)
?}
?else if (Screen&1 != "")
?{
??Sysget, M, Monitor, %Screen%
??x := MLeft, y := MTop, w := MRight-MLeft, h := MBottom-MTop
?}
?else
?{
??StringSplit, S, Screen, |
??x := S1, y := S2, w := S3, h := S4
?}

?if (x = "") || (y = "") || (w = "") || (h = "")
??return -1

?chdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, chdc), obm := SelectObject(chdc, hbm), hhdc := hhdc ? hhdc : GetDC()
?BitBlt(chdc, 0, 0, w, h, hhdc, x, y, Raster)
?ReleaseDC(hhdc)
?
?pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
?SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
?return pBitmap
}

;#####################################################################################

; Function????Gdip_BitmapFromHWND
; Description???Uses PrintWindow to get a handle to the specified window and return a bitmap from it
;
; hwnd?????handle to the window to get a bitmap from
;
; return????If the function succeeds, the return value is a pointer to a gdi+ bitmap
;
; notes?????Window must not be not minimised in order to get a handle to it's client area

Gdip_BitmapFromHWND(hwnd)
{
?WinGetPos,,, Width, Height, ahk_id %hwnd%
?hbm := CreateDIBSection(Width, Height), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
?PrintWindow(hwnd, hdc)
?pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
?SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
?return pBitmap
}

;#####################################################################################

; Function??? ???CreateRectF
; Description???Creates a RectF object, containing a the coordinates and dimensions of a rectangle
;
; RectF?????? ???Name to call the RectF object
; x??????????? ???x-coordinate of the upper left corner of the rectangle
; y??????????? ???y-coordinate of the upper left corner of the rectangle
; w??????????? ???Width of the rectangle
; h??????????? ???Height of the rectangle
;
; return????? ???No return value

CreateRectF(ByRef RectF, x, y, w, h)
{
?? VarSetCapacity(RectF, 16)
?? NumPut(x, RectF, 0, "float"), NumPut(y, RectF, 4, "float"), NumPut(w, RectF, 8, "float"), NumPut(h, RectF, 12, "float")
}

;#####################################################################################

; Function??? ???CreateRect
; Description???Creates a Rect object, containing a the coordinates and dimensions of a rectangle
;
; RectF?????? ???Name to call the RectF object
; x??????????? ???x-coordinate of the upper left corner of the rectangle
; y??????????? ???y-coordinate of the upper left corner of the rectangle
; w??????????? ???Width of the rectangle
; h??????????? ???Height of the rectangle
;
; return????? ???No return value

CreateRect(ByRef Rect, x, y, w, h)
{
?VarSetCapacity(Rect, 16)
?NumPut(x, Rect, 0, "uint"), NumPut(y, Rect, 4, "uint"), NumPut(w, Rect, 8, "uint"), NumPut(h, Rect, 12, "uint")
}
;#####################################################################################

; Function????? ?CreateSizeF
; Description???Creates a SizeF object, containing an 2 values
;
; SizeF???????? ??Name to call the SizeF object
; w??????????? ???w-value for the SizeF object
; h??????????? ???h-value for the SizeF object
;
; return????? ???No Return value

CreateSizeF(ByRef SizeF, w, h)
{
?? VarSetCapacity(SizeF, 8)
?? NumPut(w, SizeF, 0, "float"), NumPut(h, SizeF, 4, "float")????
}
;#####################################################################################

; Function????? ?CreatePointF
; Description???Creates a SizeF object, containing an 2 values
;
; SizeF???????? ??Name to call the SizeF object
; w??????????? ???w-value for the SizeF object
; h??????????? ???h-value for the SizeF object
;
; return????? ???No Return value

CreatePointF(ByRef PointF, x, y)
{
?? VarSetCapacity(PointF, 8)
?? NumPut(x, PointF, 0, "float"), NumPut(y, PointF, 4, "float")????
}
;#####################################################################################

; Function????CreateDIBSection
; Description???The CreateDIBSection function creates a DIB (Device Independent Bitmap) that applications can write to directly
;
; w??????width of the bitmap to create
; h??????height of the bitmap to create
; hdc?????a handle to the device context to use the palette from
; bpp?????bits per pixel (32 = ARGB)
; ppvBits????A pointer to a variable that receives a pointer to the location of the DIB bit values
;
; return????returns a DIB. A gdi bitmap
;
; notes?????ppvBits will receive the location of the pixels in the DIB

CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0)
{
?hdc2 := hdc ? hdc : GetDC()
?VarSetCapacity(bi, 40, 0)
?NumPut(w, bi, 4), NumPut(h, bi, 8), NumPut(40, bi, 0), NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16), NumPut(bpp, bi, 14, "ushort")
?hbm := DllCall("CreateDIBSection", "uint" , hdc2, "uint" , &bi, "uint" , 0, "uint*", ppvBits, "uint" , 0, "uint" , 0)

?if !hdc
??ReleaseDC(hdc2)
?return hbm
}

;#####################################################################################

; Function????PrintWindow
; Description???The PrintWindow function copies a visual window into the specified device context (DC), typically a printer DC
;
; hwnd?????A handle to the window that will be copied
; hdc?????A handle to the device context
; Flags?????Drawing options
;
; return????If the function succeeds, it returns a nonzero value
;
; PW_CLIENTONLY???= 1

PrintWindow(hwnd, hdc, Flags=0)
{
?return DllCall("PrintWindow", "uint", hwnd, "uint", hdc, "uint", Flags)
}

;#####################################################################################

; Function????DestroyIcon
; Description???Destroys an icon and frees any memory the icon occupied
;
; hIcon?????Handle to the icon to be destroyed. The icon must not be in use
;
; return????If the function succeeds, the return value is nonzero

DestroyIcon(hIcon)
{
?? return DllCall("DestroyIcon", "uint", hIcon)
}

;#####################################################################################

PaintDesktop(hdc)
{
?return DllCall("PaintDesktop", "uint", hdc)
}

;#####################################################################################

CreateCompatibleBitmap(hdc, w, h)
{
?return DllCall("gdi32\CreateCompatibleBitmap", "uint", hdc, "int", w, "int", h)
}

;#####################################################################################

; Function????CreateCompatibleDC
; Description???This function creates a memory device context (DC) compatible with the specified device
;
; hdc?????Handle to an existing device context?????
;
; return????returns the handle to a device context or 0 on failure
;
; notes?????If this handle is 0 (by default), the function creates a memory device context compatible with the application's current screen

CreateCompatibleDC(hdc=0)
{
?? return DllCall("CreateCompatibleDC", "uint", hdc)
}

;#####################################################################################

; Function????SelectObject
; Description???The SelectObject function selects an object into the specified device context (DC). The new object replaces the previous object of the same type
;
; hdc?????Handle to a DC
; hgdiobj????A handle to the object to be selected into the DC
;
; return????If the selected object is not a region and the function succeeds, the return value is a handle to the object being replaced
;
; notes?????The specified object must have been created by using one of the following functions
;??????Bitmap - CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDIBitmap, CreateDIBSection (A single bitmap cannot be selected into more than one DC at the same time)
;??????Brush - CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush
;??????Font - CreateFont, CreateFontIndirect
;??????Pen - CreatePen, CreatePenIndirect
;??????Region - CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreateRectRgn, CreateRectRgnIndirect
;
; notes?????If the selected object is a region and the function succeeds, the return value is one of the following value
;
; SIMPLEREGION???= 2 Region consists of a single rectangle
; COMPLEXREGION???= 3 Region consists of more than one rectangle
; NULLREGION???= 1 Region is empty

SelectObject(hdc, hgdiobj)
{
?? return DllCall("SelectObject", "uint", hdc, "uint", hgdiobj)
}

;#####################################################################################

; Function????DeleteObject
; Description???This function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object
;??????After the object is deleted, the specified handle is no longer valid
;
; hObject????Handle to a logical pen, brush, font, bitmap, region, or palette to delete
;
; return????Nonzero indicates success. Zero indicates that the specified handle is not valid or that the handle is currently selected into a device context

DeleteObject(hObject)
{
?? return DllCall("DeleteObject", "uint", hObject)
}

;#####################################################################################

; Function????GetDC
; Description???This function retrieves a handle to a display device context (DC) for the client area of the specified window.
;??????The display device context can be used in subsequent graphics display interface (GDI) functions to draw in the client area of the window.
;
; hwnd?????Handle to the window whose device context is to be retrieved. If this value is NULL, GetDC retrieves the device context for the entire screen?????
;
; return????The handle the device context for the specified window's client area indicates success. NULL indicates failure

GetDC(hwnd=0)
{
?return DllCall("GetDC", "uint", hwnd)
}

;#####################################################################################

; DCX_CACHE = 0x2
; DCX_CLIPCHILDREN = 0x8
; DCX_CLIPSIBLINGS = 0x10
; DCX_EXCLUDERGN = 0x40
; DCX_EXCLUDEUPDATE = 0x100
; DCX_INTERSECTRGN = 0x80
; DCX_INTERSECTUPDATE = 0x200
; DCX_LOCKWINDOWUPDATE = 0x400
; DCX_NORECOMPUTE = 0x100000
; DCX_NORESETATTRS = 0x4
; DCX_PARENTCLIP = 0x20
; DCX_VALIDATE = 0x200000
; DCX_WINDOW = 0x1

GetDCEx(hwnd, flags=0, hrgnClip=0)
{
??? return DllCall("GetDCEx", "uint", hwnd, "uint", hrgnClip, "int", flags)
}

;#####################################################################################

; Function????ReleaseDC
; Description???This function releases a device context (DC), freeing it for use by other applications. The effect of ReleaseDC depends on the type of device context
;
; hdc?????Handle to the device context to be released
; hwnd?????Handle to the window whose device context is to be released
;
; return????1 = released
;??????0 = not released
;
; notes?????The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common device context
;??????An application cannot use the ReleaseDC function to release a device context that was created by calling the CreateDC function; instead, it must use the DeleteDC function.

ReleaseDC(hdc, hwnd=0)
{
?? return DllCall("ReleaseDC", "uint", hwnd, "uint", hdc)
}

;#####################################################################################

; Function????DeleteDC
; Description???The DeleteDC function deletes the specified device context (DC)
;
; hdc?????A handle to the device context
;
; return????If the function succeeds, the return value is nonzero
;
; notes?????An application must not delete a DC whose handle was obtained by calling the GetDC function. Instead, it must call the ReleaseDC function to free the DC

DeleteDC(hdc)
{
?? return DllCall("DeleteDC", "uint", hdc)
}
;#####################################################################################

; Function????Gdip_LibraryVersion
; Description???Get the current library version
;
; return????the library version
;
; notes?????This is useful for non compiled programs to ensure that a person doesn't run an old version when testing your scripts

Gdip_LibraryVersion()
{
?return 1.45
}

;#####################################################################################

; Function:??? ???Gdip_BitmapFromBRA
; Description: ???Gets a pointer to a gdi+ bitmap from a BRA file
;
; BRAFromMemIn???The variable for a BRA file read to memory
; File?????The name of the file, or its number that you would like (This depends on alternate parameter)
; Alternate????Changes whether the File parameter is the file name or its number
;
; return????? ???If the function succeeds, the return value is a pointer to a gdi+ bitmap
;??????-1 = The BRA variable is empty
;??????-2 = The BRA has an incorrect header
;??????-3 = The BRA has information missing
;??????-4 = Could not find file inside the BRA

Gdip_BitmapFromBRA(ByRef BRAFromMemIn, File, Alternate=0)
{
?if !BRAFromMemIn
??return -1
?Loop, Parse, BRAFromMemIn, `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(BRAFromMemIn, "mi`n)^" (Alternate ? File "\|.+?\|(\d+)\|(\d+)" : "\d+\|" File "\|(\d+)\|(\d+)") "$", FileInfo)
?if !FileInfo
??return -4

?hData := DllCall("GlobalAlloc", "uint", 2, "uint", FileInfo2)
?pData := DllCall("GlobalLock", "uint", hData)
?DllCall("RtlMoveMemory", "uint", pData, "uint", &BRAFromMemIn+Info2+FileInfo1, "uint", FileInfo2)
?DllCall("GlobalUnlock", "uint", hData)
?DllCall("ole32\CreateStreamOnHGlobal", "uint", hData, "int", 1, "uint*", pStream)
?DllCall("gdiplus\GdipCreateBitmapFromStream", "uint", pStream, "uint*", pBitmap)
?DllCall(NumGet(NumGet(1*pStream)+8), "uint", pStream)
?return pBitmap
}

;#####################################################################################

; Function????Gdip_DrawRectangle
; Description???This function uses a pen to draw the outline of a rectangle into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x??????x-coordinate of the top left of the rectangle
; y??????y-coordinate of the top left of the rectangle
; w??????width of the rectanlge
; h??????height of the rectangle
;
; return????status enumeration. 0 = success
;
; notes?????as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h)
{
?? return DllCall("gdiplus\GdipDrawRectangle", "uint", pGraphics, "uint", pPen, "float", x, "float", y, "float", w, "float", h)
}

;#####################################################################################

; Function????Gdip_DrawRoundedRectangle
; Description???This function uses a pen to draw the outline of a rounded rectangle into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x??????x-coordinate of the top left of the rounded rectangle
; y??????y-coordinate of the top left of the rounded rectangle
; w??????width of the rectanlge
; h??????height of the rectangle
; r??????radius of the rounded corners
;
; return????status enumeration. 0 = success
;
; notes?????as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

Gdip_DrawRoundedRectangle(pGraphics, pPen, x, y, w, h, r)
{
?Gdip_SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
?Gdip_SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
?Gdip_SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
?Gdip_SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
?E := Gdip_DrawRectangle(pGraphics, pPen, x, y, w, h)
?Gdip_ResetClip(pGraphics)
?Gdip_SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
?Gdip_SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
?Gdip_DrawEllipse(pGraphics, pPen, x, y, 2*r, 2*r)
?Gdip_DrawEllipse(pGraphics, pPen, x+w-(2*r), y, 2*r, 2*r)
?Gdip_DrawEllipse(pGraphics, pPen, x, y+h-(2*r), 2*r, 2*r)
?Gdip_DrawEllipse(pGraphics, pPen, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
?Gdip_ResetClip(pGraphics)
?return E
}

;#####################################################################################

; Function????Gdip_DrawEllipse
; Description???This function uses a pen to draw the outline of an ellipse into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x??????x-coordinate of the top left of the rectangle the ellipse will be drawn into
; y??????y-coordinate of the top left of the rectangle the ellipse will be drawn into
; w??????width of the ellipse
; h??????height of the ellipse
;
; return????status enumeration. 0 = success
;
; notes?????as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

Gdip_DrawEllipse(pGraphics, pPen, x, y, w, h)
{
?? return DllCall("gdiplus\GdipDrawEllipse", "uint", pGraphics, "uint", pPen, "float", x, "float", y, "float", w, "float", h)
}

;#####################################################################################

; Function????Gdip_DrawBezier
; Description???This function uses a pen to draw the outline of a bezier (a weighted curve) into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x1?????x-coordinate of the start of the bezier
; y1?????y-coordinate of the start of the bezier
; x2?????x-coordinate of the first arc of the bezier
; y2?????y-coordinate of the first arc of the bezier
; x3?????x-coordinate of the second arc of the bezier
; y3?????y-coordinate of the second arc of the bezier
; x4?????x-coordinate of the end of the bezier
; y4?????y-coordinate of the end of the bezier
;
; return????status enumeration. 0 = success
;
; notes?????as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

Gdip_DrawBezier(pGraphics, pPen, x1, y1, x2, y2, x3, y3, x4, y4)
{
?? return DllCall("gdiplus\GdipDrawBezier", "uint", pgraphics, "uint", pPen
?? , "float", x1, "float", y1, "float", x2, "float", y2
?? , "float", x3, "float", y3, "float", x4, "float", y4)
}

;#####################################################################################

; Function????Gdip_DrawArc
; Description???This function uses a pen to draw the outline of an arc into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x??????x-coordinate of the start of the arc
; y??????y-coordinate of the start of the arc
; w??????width of the arc
; h??????height of the arc
; StartAngle???specifies the angle between the x-axis and the starting point of the arc
; SweepAngle???specifies the angle between the starting and ending points of the arc
;
; return????status enumeration. 0 = success
;
; notes?????as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

Gdip_DrawArc(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle)
{
?? return DllCall("gdiplus\GdipDrawArc", "uint", pGraphics, "uint", pPen, "float", x
?? , "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}

;#####################################################################################

; Function????Gdip_DrawPie
; Description???This function uses a pen to draw the outline of a pie into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x??????x-coordinate of the start of the pie
; y??????y-coordinate of the start of the pie
; w??????width of the pie
; h??????height of the pie
; StartAngle???specifies the angle between the x-axis and the starting point of the pie
; SweepAngle???specifies the angle between the starting and ending points of the pie
;
; return????status enumeration. 0 = success
;
; notes?????as all coordinates are taken from the top left of each pixel, then the entire width/height should be specified as subtracting the pen width

Gdip_DrawPie(pGraphics, pPen, x, y, w, h, StartAngle, SweepAngle)
{
?? return DllCall("gdiplus\GdipDrawPie", "uint", pGraphics, "uint", pPen, "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}

;#####################################################################################

; Function????Gdip_DrawLine
; Description???This function uses a pen to draw a line into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; x1?????x-coordinate of the start of the line
; y1?????y-coordinate of the start of the line
; x2?????x-coordinate of the end of the line
; y2?????y-coordinate of the end of the line
;
; return????status enumeration. 0 = success??

Gdip_DrawLine(pGraphics, pPen, x1, y1, x2, y2)
{
?? return DllCall("gdiplus\GdipDrawLine", "uint", pGraphics, "uint", pPen
?? , "float", x1, "float", y1, "float", x2, "float", y2)
}

;#####################################################################################

; Function????Gdip_DrawLines
; Description???This function uses a pen to draw a series of joined lines into the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pPen?????Pointer to a pen
; Points????the coordinates of all the points passed as x1,y1|x2,y2|x3,y3.....
;
; return????status enumeration. 0 = success????

Gdip_DrawLines(pGraphics, pPen, 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\GdipDrawLines", "uint", pGraphics, "uint", pPen, "uint", &PointF, "int", Points0)
}

;#####################################################################################

; Function????Gdip_FillRectangle
; Description???This function uses a brush to fill a rectangle in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; x??????x-coordinate of the top left of the rectangle
; y??????y-coordinate of the top left of the rectangle
; w??????width of the rectanlge
; h??????height of the rectangle
;
; return????status enumeration. 0 = success

Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
{
?? return DllCall("gdiplus\GdipFillRectangle", "uint", pGraphics, "int", pBrush
?? , "float", x, "float", y, "float", w, "float", h)
}

;#####################################################################################

; Function????Gdip_FillRoundedRectangle
; Description???This function uses a brush to fill a rounded rectangle in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; x??????x-coordinate of the top left of the rounded rectangle
; y??????y-coordinate of the top left of the rounded rectangle
; w??????width of the rectanlge
; h??????height of the rectangle
; r??????radius of the rounded corners
;
; return????status enumeration. 0 = success

Gdip_FillRoundedRectangle(pGraphics, pBrush, x, y, w, h, r)
{
?Region := Gdip_GetClipRegion(pGraphics)
?Gdip_SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
?Gdip_SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
?Gdip_SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
?Gdip_SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
?E := Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
?Gdip_SetClipRegion(pGraphics, Region, 0)
?Gdip_SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
?Gdip_SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
?Gdip_FillEllipse(pGraphics, pBrush, x, y, 2*r, 2*r)
?Gdip_FillEllipse(pGraphics, pBrush, x+w-(2*r), y, 2*r, 2*r)
?Gdip_FillEllipse(pGraphics, pBrush, x, y+h-(2*r), 2*r, 2*r)
?Gdip_FillEllipse(pGraphics, pBrush, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
?Gdip_SetClipRegion(pGraphics, Region, 0)
?Gdip_DeleteRegion(Region)
?return E
}

;#####################################################################################

; Function????Gdip_FillPolygon
; Description???This function uses a brush to fill a polygon in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; Points????the coordinates of all the points passed as x1,y1|x2,y2|x3,y3.....
;
; return????status enumeration. 0 = success
;
; notes?????Alternate will fill the polygon as a whole, wheras winding will fill each new "segment"
; Alternate ???= 0
; Winding ????= 1

Gdip_FillPolygon(pGraphics, pBrush, Points, FillMode=0)
{
?? 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\GdipFillPolygon", "uint", pGraphics, "uint", pBrush, "uint", &PointF, "int", Points0, "int", FillMode)
}

;#####################################################################################

; Function????Gdip_FillPie
; Description???This function uses a brush to fill a pie in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; x??????x-coordinate of the top left of the pie
; y??????y-coordinate of the top left of the pie
; w??????width of the pie
; h??????height of the pie
; StartAngle???specifies the angle between the x-axis and the starting point of the pie
; SweepAngle???specifies the angle between the starting and ending points of the pie
;
; return????status enumeration. 0 = success

Gdip_FillPie(pGraphics, pBrush, x, y, w, h, StartAngle, SweepAngle)
{
?? return DllCall("gdiplus\GdipFillPie", "uint", pGraphics, "uint", pBrush
?? , "float", x, "float", y, "float", w, "float", h, "float", StartAngle, "float", SweepAngle)
}

;#####################################################################################

; Function????Gdip_FillEllipse
; Description???This function uses a brush to fill an ellipse in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; x??????x-coordinate of the top left of the ellipse
; y??????y-coordinate of the top left of the ellipse
; w??????width of the ellipse
; h??????height of the ellipse
;
; return????status enumeration. 0 = success

Gdip_FillEllipse(pGraphics, pBrush, x, y, w, h)
{
?return DllCall("gdiplus\GdipFillEllipse", "uint", pGraphics, "uint", pBrush, "float", x, "float", y, "float", w, "float", h)
}

;#####################################################################################

; Function????Gdip_FillRegion
; Description???This function uses a brush to fill a region in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; Region????Pointer to a Region
;
; return????status enumeration. 0 = success
;
; notes?????You can create a region Gdip_CreateRegion() and then add to this

Gdip_FillRegion(pGraphics, pBrush, Region)
{
?return DllCall("gdiplus\GdipFillRegion", "uint", pGraphics, "uint", pBrush, "uint", Region)
}

;#####################################################################################

; Function????Gdip_FillPath
; Description???This function uses a brush to fill a path in the Graphics of a bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBrush????Pointer to a brush
; Region????Pointer to a Path
;
; return????status enumeration. 0 = success

Gdip_FillPath(pGraphics, pBrush, Path)
{
?return DllCall("gdiplus\GdipFillPath", "uint", pGraphics, "uint", pBrush, "uint", Path)
}

;#####################################################################################

; Function????Gdip_DrawImagePointsRect
; Description???This function draws a bitmap into the Graphics of another bitmap and skews it
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBitmap????Pointer to a bitmap to be drawn
; Points????Points passed as x1,y1|x2,y2|x3,y3 (3 points: top left, top right, bottom left) describing the drawing of the bitmap
; sx?????x-coordinate of source upper-left corner
; sy?????y-coordinate of source upper-left corner
; sw?????width of source rectangle
; sh?????height of source rectangle
; Matrix????a matrix used to alter image attributes when drawing
;
; return????status enumeration. 0 = success
;
; notes?????if sx,sy,sw,sh are missed then the entire source bitmap will be used
;??????Matrix can be omitted to just draw with no alteration to ARGB
;??????Matrix may be passed as a digit from 0 - 1 to change just transparency
;??????Matrix can be passed as a matrix with any delimiter

Gdip_DrawImagePointsRect(pGraphics, pBitmap, Points, sx="", sy="", sw="", sh="", Matrix=1)
{
?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")
?}

?if (Matrix&1 = "")
??ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
?else if (Matrix != 1)
??ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")
??
?if (sx = "" && sy = "" && sw = "" && sh = "")
?{
??sx := 0, sy := 0
??sw := Gdip_GetImageWidth(pBitmap)
??sh := Gdip_GetImageHeight(pBitmap)
?}

?E := DllCall("gdiplus\GdipDrawImagePointsRect", "uint", pGraphics, "uint", pBitmap
?, "uint", &PointF, "int", Points0, "float", sx, "float", sy, "float", sw, "float", sh
?, "int", 2, "uint", ImageAttr, "uint", 0, "uint", 0)
?if ImageAttr
??Gdip_DisposeImageAttributes(ImageAttr)
?return E
}

;#####################################################################################

; Function????Gdip_DrawImage
; Description???This function draws a bitmap into the Graphics of another bitmap
;
; pGraphics????Pointer to the Graphics of a bitmap
; pBitmap????Pointer to a bitmap to be drawn
; dx?????x-coord of destination upper-left corner
; dy?????y-coord of destination upper-left corner
; dw?????width of destination image
; dh?????height of destination image
; sx?????x-coordinate of source upper-left corner
; sy?????y-coordinate of source upper-left corner
; sw?????width of source image
; sh?????height of source image
; Matrix????a matrix used to alter image attributes when drawing
;
; return????status enumeration. 0 = success
;
; notes?????if sx,sy,sw,sh are missed then the entire source bitmap will be used
;??????Gdip_DrawImage performs faster
;??????Matrix can be omitted to just draw with no alteration to ARGB
;??????Matrix may be passed as a digit from 0 - 1 to change just transparency
;??????Matrix can be passed as a matrix with any delimiter. For example:
;??????MatrixBright=
;??????(
;??????1.5??|0??|0??|0??|0
;??????0??|1.5?|0??|0??|0
;??????0??|0??|1.5?|0??|0
;??????0??|0??|0??|1??|0
;??????0.05?|0.05?|0.05?|0??|1
;??????)
;
; notes?????MatrixBright = 1.5|0|0|0|0|0|1.5|0|0|0|0|0|1.5|0|0|0|0|0|1|0|0.05|0.05|0.05|0|1
;??????MatrixGreyScale = 0.299|0.299|0.299|0|0|0.587|0.587|0.587|0|0|0.114|0.114|0.114|0|0|0|0|0|1|0|0|0|0|0|1
;??????MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1

Gdip_DrawImage(pGraphics, pBitmap, dx="", dy="", dw="", dh="", sx="", sy="", sw="", sh="", Matrix=1)
{
?if (Matrix&1 = "")
??ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
?else if (Matrix != 1)
??ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")

?if (sx = "" && sy = "" && sw = "" && sh = "")
?{
??if (dx = "" && dy = "" && dw = "" && dh = "")
??{
???sx := dx := 0, sy := dy := 0
???sw := dw := Gdip_GetImageWidth(pBitmap)
???sh := dh := Gdip_GetImageHeight(pBitmap)
??}
??else
??{
???sx := sy := 0
???sw := Gdip_GetImageWidth(pBitmap)
???sh := Gdip_GetImageHeight(pBitmap)
??}
?}

?E := DllCall("gdiplus\GdipDrawImageRectRect", "uint", pGraphics, "uint", pBitmap
?, "float", dx, "float", dy, "float", dw, "float", dh
?, "float", sx, "float", sy, "float", sw, "float", sh
?, "int", 2, "uint", ImageAttr, "uint", 0, "uint", 0)
?if ImageAttr
??Gdip_DisposeImageAttributes(ImageAttr)
?return E
}

;#####################################################################################

; Function????Gdip_SetImageAttributesColorMatrix
; Description???This function creates an image matrix ready for drawing
;
; Matrix????a matrix used to alter image attributes when drawing
;??????passed with any delimeter
;
; return????returns an image matrix on sucess or 0 if it fails
;
; notes?????MatrixBright = 1.5|0|0|0|0|0|1.5|0|0|0|0|0|1.5|0|0|0|0|0|1|0|0.05|0.05|0.05|0|1
;??????MatrixGreyScale = 0.299|0.299|0.299|0|0|0.587|0.587|0.587|0|0|0.114|0.114|0.114|0|0|0|0|0|1|0|0|0|0|0|1
;??????MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1

Gdip_SetImageAttributesColorMatrix(Matrix)
{
?VarSetCapacity(ColourMatrix, 100, 0)
?Matrix := RegExReplace(RegExReplace(Matrix, "^[^\d-\.]+([\d\.])", "$1", "", 1), "[^\d-\.]+", "|")
?StringSplit, Matrix, Matrix, |
?Loop, 25
?{
??Matrix := (Matrix%A_Index% != "") ? Matrix%A_Index% : Mod(A_Index-1, 6) ? 0 : 1
??NumPut(Matrix, ColourMatrix, (A_Index-1)*4, "float")
?}
?DllCall("gdiplus\GdipCreateImageAttributes", "uint*", ImageAttr)
?DllCall("gdiplus\GdipSetImageAttributesColorMatrix", "uint", ImageAttr, "int", 1, "int", 1, "uint", &ColourMatrix, "int", 0, "int", 0)
?return ImageAttr
}

;#####################################################################################

; Function????Gdip_GraphicsFromImage
; Description???This function gets the graphics for a bitmap used for drawing functions
;
; pBitmap????Pointer to a bitmap to get the pointer to its graphics
;
; return????returns a pointer to the graphics of a bitmap
;
; notes?????a bitmap can be drawn into the graphics of another bitmap

Gdip_GraphicsFromImage(pBitmap)
{
??? DllCall("gdiplus\GdipGetImageGraphicsContext", "uint", pBitmap, "uint*", pGraphics)
??? return pGraphics
}

;#####################################################################################

; Function????Gdip_GraphicsFromHDC
; Description???This function gets the graphics from the handle to a device context
;
; hdc?????This is the handle to the device context
;
; return????returns a pointer to the graphics of a bitmap
;
; notes?????You can draw a bitmap into the graphics of another bitmap

Gdip_GraphicsFromHDC(hdc)
{
??? DllCall("gdiplus\GdipCreateFromHDC", "uint", hdc, "uint*", pGraphics)
??? return pGraphics
}

;#####################################################################################

; Function????Gdip_GetDC
; Description???This function gets the device context of the passed Graphics
;
; hdc?????This is the handle to the device context
;
; return????returns the device context for the graphics of a bitmap

Gdip_GetDC(pGraphics)
{
?DllCall("gdiplus\GdipGetDC", "uint", pGraphics, "uint*", hdc)
?return hdc
}

;#####################################################################################

; Function????Gdip_ReleaseDC
; Description???This function releases a device context from use for further use
;
; pGraphics????Pointer to the graphics of a bitmap
; hdc?????This is the handle to the device context
;
; return????status enumeration. 0 = success

Gdip_ReleaseDC(pGraphics, hdc)
{
?return DllCall("gdiplus\GdipReleaseDC", "uint", pGraphics, "uint", hdc)
}

;#####################################################################################

; Function????Gdip_GraphicsClear
; Description???Clears the graphics of a bitmap ready for further drawing
;
; pGraphics????Pointer to the graphics of a bitmap
; ARGB?????The colour to clear the graphics to
;
; return????status enumeration. 0 = success
;
; notes?????By default this will make the background invisible
;??????Using clipping regions you can clear a particular area on the graphics rather than clearing the entire graphics

Gdip_GraphicsClear(pGraphics, ARGB=0x00ffffff)
{
??? return DllCall("gdiplus\GdipGraphicsClear", "uint", pGraphics, "int", ARGB)
}

;#####################################################################################

; Function????Gdip_BlurBitmap
; Description???Gives a pointer to a blurred bitmap from a pointer to a bitmap
;
; pBitmap????Pointer to a bitmap to be blurred
; Blur?????The Amount to blur a bitmap by from 1 (least blur) to 100 (most blur)
;
; return????If the function succeeds, the return value is a pointer to the new blurred bitmap
;??????-1 = The blur parameter is outside the range 1-100
;
; notes?????This function will not dispose of the original bitmap

Gdip_BlurBitmap(pBitmap, Blur)
{
?if (Blur > 100) || (Blur < 1)
??return -1?
?
?sWidth := Gdip_GetImageWidth(pBitmap), sHeight := Gdip_GetImageHeight(pBitmap)
?dWidth := sWidth//Blur, dHeight := sHeight//Blur

?pBitmap1 := Gdip_CreateBitmap(dWidth, dHeight)
?G1 := Gdip_GraphicsFromImage(pBitmap1)
?Gdip_SetInterpolationMode(G1, 7)
?Gdip_DrawImage(G1, pBitmap, 0, 0, dWidth, dHeight, 0, 0, sWidth, sHeight)

?Gdip_DeleteGraphics(G1)

?pBitmap2 := Gdip_CreateBitmap(sWidth, sHeight)
?G2 := Gdip_GraphicsFromImage(pBitmap2)
?Gdip_SetInterpolationMode(G2, 7)
?Gdip_DrawImage(G2, pBitmap1, 0, 0, sWidth, sHeight, 0, 0, dWidth, dHeight)

?Gdip_DeleteGraphics(G2)
?Gdip_DisposeImage(pBitmap1)
?return pBitmap2
}

Gdip_ImageSearch(pBitmapHayStack, pBitmapNeedle, ByRef x, ByRef y, sx1="", sy1="", sx2="", sy2="", Variation=0, Trans=0, w=0, h=0, sd=0)
{
static _ImageSearch1, _ImageSearch2, _PixelSearch1, _PixelSearch2

if !_ImageSearch1
{
MCode_ImageSearch1 := "8B4C243483EC10803900538B5C2434555657750C80790100750680790200744B8B54243885D27E478B7C2430478BEA908B7424"
. "3485F67E2C8BC78D9B000000008A50013A510275128A103A5101750B8A50FF3A117504C640020083C0044E75E08B54243803FB4D75C7EB048B5424388B"
. "4424488944241C3B4424500F8D800200008B4C243C8BF90FAFF88D4402FF0FAFC1897C2418894424148DA424000000008B742444897424543B74244C0F"
. "8D300200008B74245C83FE0175648B6C243033D2453B5424380F8D5402000033F6397424347E428B4C24548B5C242C8D0C8F8BC58D4C19018A58013A59"
. "01750E8A183A1975088A58FF3A59FF740A807802000F85B60100004683C10483C0043B7424347CD38B5C2440037C243C4203EBEBA383FE020F85860000"
. "008BF88BC14A8BCBF7D8F7D98BF20FAFF38B5C243089442410894C24488D6C1E01EB068D9B0000000083FAFF0F8EC701000033F6397424347E468B4C24"
. "548B5C242C8D0C8F8BC58D4C19018A58013A5901750E8A183A1975088A58FF3A59FF740A807802000F85290100004683C10483C0043B7424347CD38B44"
. "24108B4C244803F84A03E9EBA283FE030F85840000004A8BFAF7D90FAFFB8BF3F7DE8BE8894C2410897424488D490083FAFF0F8E470100008B44243448"
. "83F8FF7E518B7424308B5C242C8D0C878D4C31018B74245403F08D74B5008D741E018A59013A5E01750E8A193A1E75088A59FF3A5EFF740A807902000F"
. "859B0000004883EE0483E90483F8FF7FD48B7424488B4C241003E94A03FEEB9583FE040F85DC00000033ED896C24488D9B00000000395424480F8DC600"
. "00008B4424344883F8FF7E4D8B4C24308B74242C8D5485008D4C0A018B54245403D08D14978D7432018A51013A5601750E8A113A1675088A51FF3A56FF"
. "74068079020075224883EE0483E90483F8FF7FD88B5424388B4C243CFF44244803F903EBEB958B5C24408B4424548B7C24188B5424388B4C243C403B44"
. "244C894424548B4424140F8CD0FDFFFF8B74241C4603C103F98974241C89442414897C24183B7424500F8C9FFDFFFF8B4C24248B5424285F5E5DC701FF"
. "FFFFFFC702FFFFFFFF83C8FF5B83C410C38B4424248B4C24548B5424285F89088B4424185E5D890233C05B83C410C3"

MCode_ImageSearch2 := "8B4C24348B54241883EC2C803900538B5C2450555657750C80790100750680790200744E8B6C244C85D27E4A8D7D0189542470"
. "8B74245085F67E298BC78D49008A50013A510275128A103A5101750B8A50FF3A117504C640020083C0044E75E08B6C244C03FBFF4C247075C78B542454"
. "EB048B6C244C8B442464894424183B44246C0F8D0C0400008B7C24588B74247C8BCF0FAFC8894C24148B8C248000000003C88D4402FF0FAFCF0FAFC789"
. "4424108B442474894C2430EB068D9B000000008B4C2460894C24643B4C24680F8DA40300008BD30FAF94248000000003D58D0CB20FB611894C24348B4C"
. "246003CE8B7424308D0C8E034C244889542438894C242CEB048B4C242C0FB6098D34013BD67F062BC83BD17D0E8B4C2434807903000F85350300008B4C"
. "247883F9010F85AD0000008B742414C7442470000000008D4D018B542470894C2424897424283B5424540F8D5C03000033ED396C24507E698B5424648D"
. "14968B7424488D7432018BFF0FB656010FB679018D1C023BFB7F2E2BD03BFA7C280FB6160FB6398D1C023BFB7F1B2BD03BFA7C150FB656FF0FB679FF8D"
. "1C023BFB7F062BD03BFA7D0A807902000F85930200004583C60483C1043B6C24507CAC8B5C245C8B7424288B4C242403742458FF44247003CBE962FFFF"
. "FF83F9020F85C60000008B5424108B4C2454498954241C8BD78BF3F7DAF7DE8BF90FAFFB8D7C2F018954242889742424897C2420894C247083F9FF0F8E"
. "9402000033ED396C24507E798B74241C8B5424648B4C24208D14968B7424488D7432018BFF0FB656010FB679018D1C023BFB7F2E2BD03BFA7C280FB616"
. "0FB6398D1C023BFB7F1B2BD03BFA7C150FB656FF0FB679FF8D1C023BFB7F062BD03BFA7D0A807902000F85C30100004583C60483C1043B6C24507CAC8B"
. "7424248B5424288B4C24700154241C4901742420E964FFFFFF83F9030F85D80000008B5424548B4C24104A894C24208BF78BCAF7DE0FAFCB8BFBF7DF89"
. "742428897C2424894C241C8954247083FAFF0F8EC90100008B6C24504D83FDFF0F8E8B0000008B7424208D14A98B4C244C8D4C0A018B54246403D58D14"
. "968B7424488D543201EB068D9B000000000FB672010FB679018D1C063BFB7F2E2BF03BFE7C280FB6320FB6398D1C063BFB7F1B2BF03BFE7C150FB672FF"
. "0FB679FF8D1C063BFB7F062BF03BFE7D0A807902000F85E30000004D83EA0483E90483FDFF7FAD8B7C24248B7424288B4C241C8B542470017424204A03"
. "CFE94AFFFFFF83F9040F851B0100008B74241433C9894C2470894C24288B4C2470897424243B4C24540F8DFB0000008B6C24504D83FDFF7E738B542428"
. "8D0CAA8B54244C8D4C11018B54246403D58D14968B7424488D5432010FB672010FB679018D1C063BFB7F2E2BF03BFE7C280FB6320FB6398D1C063BFB7F"
. "1B2BF03BFE7C150FB672FF0FB679FF8D1C063BFB7F062BF03BFE7D068079020075254D83EA0483E90483FDFF7FB18B5C245C8B74242403742458FF4424"
. "70015C2428E95CFFFFFF8B5C245C8B6C244C8B7C24588B5424388B4C24648344242C0441894C24643B4C24680F8C91FCFFFF8B74247CFF4424188B4C24"
. "18017C2410017C2414017C24303B4C246C0F8C2CFCFFFF8B4424408B4C24445F5EC700FFFFFFFF5DC701FFFFFFFF83C8FF5B83C42CC38B5424408B4424"
. "648B4C24445F89028B5424145E5D891133C05B83C42CC3"

VarSetCapacity(_ImageSearch1, StrLen(MCode_ImageSearch1)//2)
Loop % StrLen(MCode_ImageSearch1)//2 ;%
NumPut("0x" SubStr(MCode_ImageSearch1, (2*A_Index)-1, 2), _ImageSearch1, A_Index-1, "char")
MCode_ImageSearch1 := ""

VarSetCapacity(_ImageSearch2, StrLen(MCode_ImageSearch2)//2)
Loop % StrLen(MCode_ImageSearch2)//2 ;%
NumPut("0x" SubStr(MCode_ImageSearch2, (2*A_Index)-1, 2), _ImageSearch2, A_Index-1, "char")
MCode_ImageSearch2 := ""
}

if !_PixelSearch1
{
MCode_PixelAverage1 := "8B4C24148B44240833D2891189510489510889510C8951108951143BC27E54538B5C2414558B6C240C565745894424248B7C2"
. "41C3BFA7E2E8BF58D9B000000000FB646019901011151040FB6069901410811510C0FB646FF9901411011511403F34F75DC33D283C504FF4C242475C15"
. "F5E5D5BC3"

MCode_PixelAverage2 := "83EC288B4C243C568B31578D7E1983C6E7897424148B71088B4910897C24108D7E1983C6E733C08974241C8D711983C1E733D"
. "2894424288944242C897C241889742420894C242489442444394424380F8EDF0000008B7C24348B4C243C83C70253897C24105533DB895C241085C90F8"
. "EA0000000807F01000F84810000000FB60F8BF08BEA3B4C24187D063B4C241C7F0683C00183D2000FB64FFF3B4C24207D063B4C24247F0683C00183D20"
. "00FB64FFE3B4C24287D063B4C242C7F0683C00183D2008BC82BCE8BF21BF578327F0583F901722B3B7424347C257F063B4C2430721D8B5C24508B6C244"
. "C892B8B5C24108B6C2454895D00894C2430897424348B4C2444037C244843895C24103BD90F8C60FFFFFF8B74244C8B7C24144683C7048974244C897C2"
. "4143B7424400F8C34FFFFFF5D5B5F5E83C428C3"

VarSetCapacity(_PixelSearch1, StrLen(MCode_PixelAverage1)//2)
Loop % StrLen(MCode_PixelAverage1)//2 ;%
NumPut("0x" SubStr(MCode_PixelAverage1, (2*A_Index)-1, 2), _PixelSearch1, A_Index-1, "char")
MCode_PixelAverage1 := ""

VarSetCapacity(_PixelSearch2, StrLen(MCode_PixelAverage2)//2)
Loop % StrLen(MCode_PixelAverage2)//2 ;%
NumPut("0x" SubStr(MCode_PixelAverage2, (2*A_Index)-1, 2), _PixelSearch2, A_Index-1, "char")
MCode_PixelAverage2 := ""
}

if (Variation > 255 || Variation < 0)
return -2

Gdip_GetImageDimensions(pBitmapHayStack, hWidth, hHeight)
, Gdip_GetImageDimensions(pBitmapNeedle, nWidth, nHeight)

if !(hWidth && hHeight && nWidth && nHeight)
return -3
if (nWidth > hWidth || nHeight > hHeight)
return -4

;Sets/corrects resize variables
w := (w < -1) ? 0 : w
, h := (h < -1) ? 0 : h

;Resizes the needle image if w/h are set
;What a pain...
if (w || h){
;Creates a resized needle image and set pBitmapNeedle to the bitmap
if (w = -1)
sH := h, sW := nWidth / nHeight, sW := Round(sH * sW)
else if (h = -1)
sW := w, sH := nHeight / nWidth, sH := Round(sW * sH)
else
sW := w, sH := h

pTempBitmap := Gdip_CreateBitmap(sW, sH)
, pG := Gdip_GraphicsFromImage(pTempBitmap)

, Gdip_SetInterpolationMode(pG, 7)
, Gdip_DrawImage(pG, pBitmapNeedle, 0, 0, sW, sH, 0, 0, nWidth, nHeight)
, Gdip_DeleteGraphics(pG)

, pBitmapNeedle := pTempBitmap
, Gdip_GetImageDimensions(pBitmapNeedle, nWidth, nHeight)

if !(nWidth && nHeight){
Gdip_DisposeImage(pBitmapNeedle)
return -5
}
if (nWidth > hWidth || nHeight > hHeight){
Gdip_DisposeImage(pBitmapNeedle)
return -6
}
}

;Sets/corrects search box and needle scan direction
sx1 := (sx1 = "") ? 0 : sx1
, sy1 := (sy1 = "") ? 0 : sy1
, sx2 := (sx2 = "") ? hWidth-sx1 : sx2
, sy2 := (sy2 = "") ? hHeight-sy1 : sy2
, sd := (sd < 0 || sd > 4) ? 1 : sd

if (sx1 < 0 || sy1 < 0){
if (w || h)
Gdip_DisposeImage(pBitmapNeedle)
return -7
}

;Detects to-small search boxes
if ((sx2 - sx1) < nWidth || (sy2 - sy1) < nHeight){
if (w || h)
Gdip_DisposeImage(pBitmapNeedle)
return -8
}

;Prevents searching to close to the edges: it can't match 20 pixels in a 19 pixel search area
if (sx2 > (hWidth - nWidth))
sx2 := hWidth - nWidth
if (sy2 > (hHeight - nHeight))
sy2 := hHeight - nHeight

;Detects invalid search boxes
if (sx2 <= sx1 || sy2 <= sy1){
if (w || h)
Gdip_DisposeImage(pBitmapNeedle)
return -9
}

;Averages the needle in 4 chunks counting the number of pixels(R, G &? that arn't +- 25 of the average color
;and sets the search code to scan that corner first when matching the image
;Also sets a "Check this pixel first" location for the haystack instead of always starting at the corner of the image (0/0, w/h, ...)
if (sd = 0 And nWidth >= 20 And nHeight >= 20){
;Split the needle into 4 corners
pBitmap_Needle_S1 := Gdip_CloneBitmapArea(pBitmapNeedle, 0, 0, Floor(nWidth / 2), Floor(nHeight / 2))
, pBitmap_Needle_S2 := Gdip_CloneBitmapArea(pBitmapNeedle, 0, Floor(nHeight / 2), Floor(nWidth / 2), Ceil(nHeight / 2))
, pBitmap_Needle_S3 := Gdip_CloneBitmapArea(pBitmapNeedle, Floor(nWidth / 2), Floor(nHeight / 2), Ceil(nWidth / 2), Ceil(nHeight / 2))
, pBitmap_Needle_S4 := Gdip_CloneBitmapArea(pBitmapNeedle, Floor(nWidth / 2), 0, Ceil(nWidth / 2), Floor(nHeight / 2))
, Last_Score := 0
, sd := 1

;Loop through the corners one at a time
loop, 4
{
Gdip_GetImageDimensions(pBitmap_Needle_S%A_Index%, Sector_Width, Sector_Height)
if !(Sector_Width && Sector_Height){
;Cleanup
if (w || h)
Gdip_DisposeImage(pBitmapNeedle)
Loop, 4
Gdip_DisposeImage(pBitmap_Needle_S%A_Index%)

return -10
}

if (Gdip_LockBits(pBitmap_Needle_S%A_Index%, 0, 0, Sector_Width, Sector_Height, Sector_Stride, Sector_Scan, Sector_BitmapData)){
;Cleanup
if (w || h)
Gdip_DisposeImage(pBitmapNeedle)
Loop, 4
Gdip_DisposeImage(pBitmap_Needle_S%A_Index%)

return -11
}

;Average the R G B values of the pixels in this corner of the image
VarSetCapacity(Sector_Averages, 8 * 3, 0)
, DllCall(&_PixelSearch1, "UInt", Sector_Scan, "Int", Sector_Width, "Int", Sector_Height, "Int", Sector_Stride, "UInt", &Sector_Averages)

loop, 3
N := NumGet(Sector_Averages, (A_Index - 1) * 8, "Int64") // (Sector_Width * Sector_Height)
, NumPut(N, Sector_Averages, (A_Index - 1) * 8, "Int64")

;Find the total number of R G B values that do not fall within +- 25 of the averages
;Also find a pixel that does not fall within +- 25 of the R G B averages to use as a search-first location for the needle
uX := -1, uY := -1
, Sector_Score := DllCall(&_PixelSearch2, "UInt", Sector_Scan, "Int", Sector_Width, "Int", Sector_Height, "Int", Sector_Stride, "UInt", &Sector_Averages, "int*", uX, "int*", uY, "cdecl int64")
, Gdip_UnlockBits(pBitmap_Needle_S%A_Index%, Sector_BitmapData)
, Gdip_DisposeImage(pBitmap_Needle_S%A_Index%)

;Remember the corner with the highest rating
if (Sector_Score > Last_Score){
sd := A_Index, Last_Score := Sector_Score

;Records the x/y of a unique pixel (does not fall within +- 25 of the average pixel color
;None of this is used if Variation is not set
if (Variation && uX != -1 && uY != -1){
if (A_Index = 1)
suX := uX, suY := uY
else if (A_Index = 2)
suX := uX, suY := Floor(nHeight / 2) + uY
else if (A_Index = 3)
suX := Floor(nWidth / 2) + uX, suY := Floor(nHeight / 2) + uY
else if (A_Index = 4)
suX := Floor(nWidth / 2) + uX, suY := uY
}
}
}
}

if (sd = 0)
sd := 1

;Sets the default search-first location for variation searches if none was set yet
suX := (suX = "") ? 0 : suX
, suY := (suY = "") ? 0 : suY

;If Trans is used and the needle hasn't already been copied through scaling create a copy because it might be modified by the imagesearch code
if (!w && !h && Trans)
pBitmapNeedle := Gdip_CloneBitmapArea(pBitmapNeedle, 0, 0, nWidth, nHeight)

E1 := Gdip_LockBits(pBitmapHayStack, 0, 0, hWidth, hHeight, Stride1, Scan01, BitmapData1)
, E2 := Gdip_LockBits(pBitmapNeedle, 0, 0, nWidth, nHeight, Stride2, Scan02, BitmapData2)
if (E1 || E2){
if (w || h || Trans)
Gdip_DisposeImage(pBitmapNeedle)
return -12
}

;The dllcall parameters are the same for easier C code modification even though they arn't all used on the _ImageSearch1 version
x := y := 0
, E := DllCall(((Variation = 0) ? &_ImageSearch1 : &_ImageSearch2), "int*", x, "int*", y, "uint", Scan01, "uint", Scan02, "int", nWidth, "int", nHeight, "int", Stride1
, "int", Stride2, "int", sx1, "int", sy1, "int", sx2, "int", sy2, "int*", Trans, "int", Variation, "int", sd, "int", suX, "int", suY, "cdecl int")

Gdip_UnlockBits(pBitmapHayStack, BitmapData1), Gdip_UnlockBits(pBitmapNeedle, BitmapData2)

if (w || h || Trans)
Gdip_DisposeImage(pBitmapNeedle)

return (E = "") ? -13 : E
}
;#####################################################################################

; Function:???? ??Gdip_SaveBitmapToFile
; Description:? ??Saves a bitmap to a file in any supported format onto disk
;??
; pBitmap????Pointer to a bitmap
; sOutput????? ???The name of the file that the bitmap will be saved to. Supported extensions are: .BMP,.DIB,.RLE,.JPG,.JPEG,.JPE,.JFIF,.GIF,.TIF,.TIFF,.PNG
; Quality????? ???If saving as jpg (.JPG,.JPEG,.JPE,.JFIF) then quality can be 1-100 with default at maximum quality
;
; return????? ???If the function succeeds, the return value is zero, otherwise:
;??????-1 = Extension supplied is not a supported file format
;??????-2 = Could not get a list of encoders on system
;??????-3 = Could not find matching encoder for specified file format
;??????-4 = Could not get WideChar name of output file
;??????-5 = Could not save file to disk
;
; notes?????This function will use the extension supplied from the sOutput parameter to determine the output format

Gdip_SaveBitmapToFile(pBitmap, sOutput, Quality=75)
{
?SplitPath, sOutput,,, Extension
?if Extension not in 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, "uint", &ci)
?if !(nCount && nSize)
??return -2
??
?Loop, %nCount%
?{
??Location := NumGet(ci, 76*(A_Index-1)+44)
??if !A_IsUnicode
??{
???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
??}
??else
??{
???nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int",? 0, "uint", 0, "uint", 0)
???sString := ""
???Loop, %nSize%
????sString .= Chr(NumGet(Location+0, 2*(A_Index-1), "char"))
???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 Extension in .JPG,.JPEG,.JPE,.JFIF
??{
???DllCall("gdiplus\GdipGetEncoderParameterListSize", "uint", pBitmap, "uint", pCodec, "uint*", nSize)
???VarSetCapacity(EncoderParameters, nSize, 0)
???DllCall("gdiplus\GdipGetEncoderParameterList", "uint", pBitmap, "uint", pCodec, "uint", nSize, "uint", &EncoderParameters)
???Loop, % NumGet(EncoderParameters)????? ;%
???{
????if (NumGet(EncoderParameters, (28*(A_Index-1))+20) = 1) && (NumGet(EncoderParameters, (28*(A_Index-1))+24) = 6)
????{
?????? p := (28*(A_Index-1))+&EncoderParameters
?????? NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20)))
?????? break
????}
???}?????
?? }
?}

?if !A_IsUnicode
?{
??nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, "uint", &sOutput, "int", -1, "uint", 0, "int", 0)
??VarSetCapacity(wOutput, nSize*2)
??DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, "uint", &sOutput, "int", -1, "uint", &wOutput, "int", nSize)
??VarSetCapacity(wOutput, -1)
??if !VarSetCapacity(wOutput)
???return -4
??E := DllCall("gdiplus\GdipSaveImageToFile", "uint", pBitmap, "uint", &wOutput, "uint", pCodec, "uint", p ? p : 0)
?}
?else
??E := DllCall("gdiplus\GdipSaveImageToFile", "uint", pBitmap, "uint", &sOutput, "uint", pCodec, "uint", p ? p : 0)
?return E ? -5 : 0
}

;#####################################################################################

; Function????Gdip_GetPixel
; Description???Gets the ARGB of a pixel in a bitmap
;
; pBitmap????Pointer to a bitmap
; x??????x-coordinate of the pixel
; y??????y-coordinate of the pixel
;
; return????Returns the ARGB value of the pixel

Gdip_GetPixel(pBitmap, x, y)
{
?DllCall("gdiplus\GdipBitmapGetPixel", "uint", pBitmap, "int", x, "int", y, "uint*", ARGB)
?return ARGB
}

;#####################################################################################

; Function????Gdip_SetPixel
; Description???Sets the ARGB of a pixel in a bitmap
;
; pBitmap????Pointer to a bitmap
; x??????x-coordinate of the pixel
; y??????y-coordinate of the pixel
;
; return????status enumeration. 0 = success

Gdip_SetPixel(pBitmap, x, y, ARGB)
{
?? return DllCall("gdiplus\GdipBitmapSetPixel", "uint", pBitmap, "int", x, "int", y, "int", ARGB)
}

;#####################################################################################

; Function????Gdip_GetImageWidth
; Description???Gives the width of a bitmap
;
; pBitmap????Pointer to a bitmap
;
; return????Returns the width in pixels of the supplied bitmap

Gdip_GetImageWidth(pBitmap)
{
?? DllCall("gdiplus\GdipGetImageWidth", "uint", pBitmap, "uint*", Width)
?? return Width
}

;#####################################################################################

; Function????Gdip_GetImageHeight
; Description???Gives the height of a bitmap
;
; pBitmap????Pointer to a bitmap
;
; return????Returns the height in pixels of the supplied bitmap

Gdip_GetImageHeight(pBitmap)
{
?? DllCall("gdiplus\GdipGetImageHeight", "uint", pBitmap, "uint*", Height)
?? return Height
}

;#####################################################################################

; Function????Gdip_GetDimensions
; Description???Gives the width and height of a bitmap
;
; pBitmap????Pointer to a bitmap
; Width?????ByRef variable. This variable will be set to the width of the bitmap
; Height????ByRef variable. This variable will be set to the height of the bitmap
;
; return????No return value
;??????Gdip_GetDimensions(pBitmap, ThisWidth, ThisHeight) will set ThisWidth to the width and ThisHeight to the height

Gdip_GetImageDimensions(pBitmap, ByRef Width, ByRef Height)
{
?DllCall("gdiplus\GdipGetImageWidth", "uint", pBitmap, "uint*", Width)
?DllCall("gdiplus\GdipGetImageHeight", "uint", pBitmap, "uint*", Height)
}

;#####################################################################################

Gdip_GetDimensions(pBitmap, ByRef Width, ByRef Height)
{
?Gdip_GetImageDimensions(pBitmap, Width, Height)
}

;#####################################################################################

Gdip_GetImagePixelFormat(pBitmap)
{
?DllCall("gdiplus\GdipGetImagePixelFormat", "uint", pBitmap, "uint*", Format)
?return Format
}

;#####################################################################################

; Function????Gdip_GetDpiX
; Description???Gives the horizontal dots per inch of the graphics of a bitmap
;
; pBitmap????Pointer to a bitmap
; Width?????ByRef variable. This variable will be set to the width of the bitmap
; Height????ByRef variable. This variable will be set to the height of the bitmap
;
; return????No return value
;??????Gdip_GetDimensions(pBitmap, ThisWidth, ThisHeight) will set ThisWidth to the width and ThisHeight to the height

Gdip_GetDpiX(pGraphics)
{
?DllCall("gdiplus\GdipGetDpiX", "uint", pGraphics, "float*", dpix)
?return Round(dpix)
}

;#####################################################################################

Gdip_GetDpiY(pGraphics)
{
?DllCall("gdiplus\GdipGetDpiY", "uint", pGraphics, "float*", dpiy)
?return Round(dpiy)
}

;#####################################################################################

Gdip_GetImageHorizontalResolution(pBitmap)
{
?DllCall("gdiplus\GdipGetImageHorizontalResolution", "uint", pBitmap, "float*", dpix)
?return Round(dpix)
}

;#####################################################################################

Gdip_GetImageVerticalResolution(pBitmap)
{
?DllCall("gdiplus\GdipGetImageVerticalResolution", "uint", pBitmap, "float*", dpiy)
?return Round(dpiy)
}

;#####################################################################################

Gdip_BitmapSetResolution(pBitmap, dpix, dpiy)
{
?return DllCall("gdiplus\GdipBitmapSetResolution", "uint", pBitmap, "float", dpix, "float", dpiy)
}

;#####################################################################################

Gdip_CreateBitmapFromFile(sFile, IconNumber=1, IconSize="")
{
?SplitPath, sFile,,, ext
?if ext in exe,dll
?{
??Sizes := IconSize ? IconSize : 256 "|" 128 "|" 64 "|" 48 "|" 32 "|" 16
??VarSetCapacity(buf, 40)
??Loop, Parse, Sizes, |
??{
???DllCall("PrivateExtractIcons", "str", sFile, "int", IconNumber-1, "int", A_LoopField, "int", A_LoopField, "uint*", hIcon, "uint*", 0, "uint", 1, "uint", 0)
???if !hIcon
????continue

???if !DllCall("GetIconInfo", "uint", hIcon, "uint", &buf)
???{
????DestroyIcon(hIcon)
????continue
???}
???hbmColor := NumGet(buf, 16)
???hbmMask? := NumGet(buf, 12)

???if !(hbmColor && DllCall("GetObject", "uint", hbmColor, "int", 24, "uint", &buf))
???{
????DestroyIcon(hIcon)
????continue
???}
???break
??}
??if !hIcon
???return -1

??Width := NumGet(buf, 4, "int"),? Height := NumGet(buf, 8, "int")
??hbm := CreateDIBSection(Width, -Height), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)

??if !DllCall("DrawIconEx", "uint", hdc, "int", 0, "int", 0, "uint", hIcon, "uint", Width, "uint", Height, "uint", 0, "uint", 0, "uint", 3)
??{
???DestroyIcon(hIcon)
???return -2
??}

??VarSetCapacity(dib, 84)
??DllCall("GetObject", "uint", hbm, "int", 84, "uint", &dib)
??Stride := NumGet(dib, 12), Bits := NumGet(dib, 20)

??DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", Stride, "int", 0x26200A, "uint", Bits, "uint*", pBitmapOld)
??pBitmap := Gdip_CreateBitmap(Width, Height), G := Gdip_GraphicsFromImage(pBitmap)
??Gdip_DrawImage(G, pBitmapOld, 0, 0, Width, Height, 0, 0, Width, Height)
??SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
??Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmapOld)
??DestroyIcon(hIcon)
?}
?else
?{
??if !A_IsUnicode
??{
???VarSetCapacity(wFile, 1023)
???DllCall("kernel32\MultiByteToWideChar", "uint", 0, "uint", 0, "uint", &sFile, "int", -1, "uint", &wFile, "int", 512)
???DllCall("gdiplus\GdipCreateBitmapFromFile", "uint", &wFile, "uint*", pBitmap)
??}
??else
???DllCall("gdiplus\GdipCreateBitmapFromFile", "uint", &sFile, "uint*", pBitmap)
?}
?return pBitmap
}

;#####################################################################################

Gdip_CreateBitmapFromHBITMAP(hBitmap, Palette=0)
{
?DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "uint", hBitmap, "uint", Palette, "uint*", pBitmap)
?return pBitmap
}

;#####################################################################################

Gdip_CreateHBITMAPFromBitmap(pBitmap, Background=0xffffffff)
{
?DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "uint", pBitmap, "uint*", hbm, "int", Background)
?return hbm
}

;#####################################################################################

Gdip_CreateBitmapFromHICON(hIcon)
{
?DllCall("gdiplus\GdipCreateBitmapFromHICON", "uint", hIcon, "uint*", pBitmap)
?return pBitmap
}

;#####################################################################################

Gdip_CreateHICONFromBitmap(pBitmap)
{
?DllCall("gdiplus\GdipCreateHICONFromBitmap", "uint", pBitmap, "uint*", hIcon)
?return hIcon
}

;#####################################################################################

Gdip_CreateBitmap(Width, Height, Format=0x26200A)
{
??? DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", 0, "int", Format, "uint", 0, "uint*", pBitmap)
??? Return pBitmap
}

;#####################################################################################

Gdip_CreateBitmapFromClipboard()
{
?if !DllCall("OpenClipboard", "uint", 0)
??return -1
?if !DllCall("IsClipboardFormatAvailable", "uint", 8)
??return -2
?if !hBitmap := DllCall("GetClipboardData", "uint", 2)
??return -3
?if !pBitmap := Gdip_CreateBitmapFromHBITMAP(hBitmap)
??return -4
?if !DllCall("CloseClipboard")
??return -5
?DeleteObject(hBitmap)
?return pBitmap
}

;#####################################################################################

Gdip_ImageSearchWithHwnd(Hwnd,Image,Byref X,Byref Y,Variation=0,Trans="")

{

gdipToken := Gdip_Startup()

bmpHaystack := Gdip_BitmapFromHwnd(Hwnd)

bmpNeedle := Gdip_CreateBitmapFromFile(Image)

RET := Gdip_ImageSearch(bmpHaystack,bmpNeedle,LIST,0,0,0,0,Variation,Trans,1,1)

Gdip_DisposeImage(bmpHaystack)

Gdip_DisposeImage(bmpNeedle)

Gdip_Shutdown(gdipToken)

StringSplit, LISTArray, LIST, `,

X := LISTArray1

Y := LISTArray2

}


;#####################################################################################

Gdip_SetBitmapToClipboard(pBitmap)
{
?hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
?DllCall("GetObject", "uint", hBitmap, "int", VarSetCapacity(oi, 84, 0), "uint", &oi)
?hdib := DllCall("GlobalAlloc", "uint", 2, "uint", 40+NumGet(oi, 44))
?pdib := DllCall("GlobalLock", "uint", hdib)
?DllCall("RtlMoveMemory", "uint", pdib, "uint", &oi+24, "uint", 40)
?DllCall("RtlMoveMemory", "Uint", pdib+40, "Uint", NumGet(oi, 20), "uint", NumGet(oi, 44))
?DllCall("GlobalUnlock", "uint", hdib)
?DllCall("DeleteObject", "uint", hBitmap)
?DllCall("OpenClipboard", "uint", 0)
?DllCall("EmptyClipboard")
?DllCall("SetClipboardData", "uint", 8, "uint", hdib)
?DllCall("CloseClipboard")
}

;#####################################################################################

Gdip_CloneBitmapArea(pBitmap, x, y, w, h, Format=0x26200A)
{
?DllCall("gdiplus\GdipCloneBitmapArea", "float", x, "float", y, "float", w, "float", h
?, "int", Format, "uint", pBitmap, "uint*", pBitmapDest)
?return pBitmapDest
}

;#####################################################################################
; Create resources
;#####################################################################################

Gdip_CreatePen(ARGB, w)
{
?? DllCall("gdiplus\GdipCreatePen1", "int", ARGB, "float", w, "int", 2, "uint*", pPen)
?? return pPen
}

;#####################################################################################

Gdip_CreatePenFromBrush(pBrush, w)
{
?DllCall("gdiplus\GdipCreatePen2", "uint", pBrush, "float", w, "int", 2, "uint*", pPen)
?return pPen
}

;#####################################################################################

Gdip_BrushCreateSolid(ARGB=0xff000000)
{
?DllCall("gdiplus\GdipCreateSolidFill", "int", ARGB, "uint*", pBrush)
?return pBrush
}

;#####################################################################################

; HatchStyleHorizontal = 0
; HatchStyleVertical = 1
; HatchStyleForwardDiagonal = 2
; HatchStyleBackwardDiagonal = 3
; HatchStyleCross = 4
; HatchStyleDiagonalCross = 5
; HatchStyle05Percent = 6
; HatchStyle10Percent = 7
; HatchStyle20Percent = 8
; HatchStyle25Percent = 9
; HatchStyle30Percent = 10
; HatchStyle40Percent = 11
; HatchStyle50Percent = 12
; HatchStyle60Percent = 13
; HatchStyle70Percent = 14
; HatchStyle75Percent = 15
; HatchStyle80Percent = 16
; HatchStyle90Percent = 17
; HatchStyleLightDownwardDiagonal = 18
; HatchStyleLightUpwardDiagonal = 19
; HatchStyleDarkDownwardDiagonal = 20
; HatchStyleDarkUpwardDiagonal = 21
; HatchStyleWideDownwardDiagonal = 22
; HatchStyleWideUpwardDiagonal = 23
; HatchStyleLightVertical = 24
; HatchStyleLightHorizontal = 25
; HatchStyleNarrowVertical = 26
; HatchStyleNarrowHorizontal = 27
; HatchStyleDarkVertical = 28
; HatchStyleDarkHorizontal = 29
; HatchStyleDashedDownwardDiagonal = 30
; HatchStyleDashedUpwardDiagonal = 31
; HatchStyleDashedHorizontal = 32
; HatchStyleDashedVertical = 33
; HatchStyleSmallConfetti = 34
; HatchStyleLargeConfetti = 35
; HatchStyleZigZag = 36
; HatchStyleWave = 37
; HatchStyleDiagonalBrick = 38
; HatchStyleHorizontalBrick = 39
; HatchStyleWeave = 40
; HatchStylePlaid = 41
; HatchStyleDivot = 42
; HatchStyleDottedGrid = 43
; HatchStyleDottedDiamond = 44
; HatchStyleShingle = 45
; HatchStyleTrellis = 46
; HatchStyleSphere = 47
; HatchStyleSmallGrid = 48
; HatchStyleSmallCheckerBoard = 49
; HatchStyleLargeCheckerBoard = 50
; HatchStyleOutlinedDiamond = 51
; HatchStyleSolidDiamond = 52
; HatchStyleTotal = 53
Gdip_BrushCreateHatch(ARGBfront, ARGBback, HatchStyle=0)
{
?DllCall("gdiplus\GdipCreateHatchBrush", "int", HatchStyle, "int", ARGBfront, "int", ARGBback, "uint*", pBrush)
?return pBrush
}

;#####################################################################################

Gdip_CreateTextureBrush(pBitmap, WrapMode=1, x=0, y=0, w="", h="")
{
?if !(w && h)
??DllCall("gdiplus\GdipCreateTexture", "uint", pBitmap, "int", WrapMode, "uint*", pBrush)
?else
??DllCall("gdiplus\GdipCreateTexture2", "uint", pBitmap, "int", WrapMode, "float", x, "float", y, "float", w, "float", h, "uint*", pBrush)
?return pBrush
}

;#####################################################################################

; WrapModeTile = 0
; WrapModeTileFlipX = 1
; WrapModeTileFlipY = 2
; WrapModeTileFlipXY = 3
; WrapModeClamp = 4
Gdip_CreateLineBrush(x1, y1, x2, y2, ARGB1, ARGB2, WrapMode=1)
{
?CreatePointF(PointF1, x1, y1), CreatePointF(PointF2, x2, y2)
?DllCall("gdiplus\GdipCreateLineBrush", "uint", &PointF1, "uint", &PointF2, "int", ARGB1, "int", ARGB2, "int", WrapMode, "uint*", LGpBrush)
?return LGpBrush
}

;#####################################################################################

; LinearGradientModeHorizontal = 0
; LinearGradientModeVertical = 1
; LinearGradientModeForwardDiagonal = 2
; LinearGradientModeBackwardDiagonal = 3
Gdip_CreateLineBrushFromRect(x, y, w, h, ARGB1, ARGB2, LinearGradientMode=1, WrapMode=1)
{
?CreateRectF(RectF, x, y, w, h)
?DllCall("gdiplus\GdipCreateLineBrushFromRect", "uint", &RectF, "int", ARGB1, "int", ARGB2, "int", LinearGradientMode, "int", WrapMode, "uint*", LGpBrush)
?return LGpBrush
}

;#####################################################################################

Gdip_CloneBrush(pBrush)
{
?DllCall("gdiplus\GdipCloneBrush", "uint", pBrush, "uint*", pBrushClone)
?return pBrushClone
}

;#####################################################################################
; Delete resources
;#####################################################################################

Gdip_DeletePen(pPen)
{
?? return DllCall("gdiplus\GdipDeletePen", "uint", pPen)
}

;#####################################################################################

Gdip_DeleteBrush(pBrush)
{
?? return DllCall("gdiplus\GdipDeleteBrush", "uint", pBrush)
}

;#####################################################################################

Gdip_DisposeImage(pBitmap)
{
?? return DllCall("gdiplus\GdipDisposeImage", "uint", pBitmap)
}

;#####################################################################################

Gdip_DeleteGraphics(pGraphics)
{
?? return DllCall("gdiplus\GdipDeleteGraphics", "uint", pGraphics)
}

;#####################################################################################

Gdip_DisposeImageAttributes(ImageAttr)
{
?return DllCall("gdiplus\GdipDisposeImageAttributes", "uint", ImageAttr)
}

;#####################################################################################

Gdip_DeleteFont(hFont)
{
?? return DllCall("gdiplus\GdipDeleteFont", "uint", hFont)
}

;#####################################################################################

Gdip_DeleteStringFormat(hFormat)
{
?? return DllCall("gdiplus\GdipDeleteStringFormat", "uint", hFormat)
}

;#####################################################################################

Gdip_DeleteFontFamily(hFamily)
{
?? return DllCall("gdiplus\GdipDeleteFontFamily", "uint", hFamily)
}

;#####################################################################################

Gdip_DeleteMatrix(Matrix)
{
?? return DllCall("gdiplus\GdipDeleteMatrix", "uint", Matrix)
}

;#####################################################################################
; Text functions
;#####################################################################################

Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0)
{
?IWidth := Width, IHeight:= Height
?
?RegExMatch(Options, "i)X([\-\d\.]+)(p*)", xpos)
?RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
?RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
?RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
?RegExMatch(Options, "i)C(?!(entre|enter))([a-f\d]+)", Colour)
?RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
?RegExMatch(Options, "i)NoWrap", NoWrap)
?RegExMatch(Options, "i)R(\d)", Rendering)
?RegExMatch(Options, "i)S(\d+)(p*)", Size)

?if !Gdip_DeleteBrush(Gdip_CloneBrush(Colour2))
??PassBrush := 1, pBrush := Colour2
?
?if !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
??return -1

?Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
?Loop, Parse, Styles, |
?{
??if RegExMatch(Options, "\b" A_loopField)
??Style |= (A_LoopField != "StrikeOut") ? (A_Index-1) : 8
?}
?
?Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
?Loop, Parse, Alignments, |
?{
??if RegExMatch(Options, "\b" A_loopField)
???Align |= A_Index//2.1????? ; 0|0|1|1|2|2
?}

?xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
?ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
?Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
?Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
?if !PassBrush
??Colour := "0x" (Colour2 ? Colour2 : "ff000000")
?Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
?Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12

?hFamily := Gdip_FontFamilyCreate(Font)
?hFont := Gdip_FontCreate(hFamily, Size, Style)
?FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
?hFormat := Gdip_StringFormatCreate(FormatStyle)
?pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)
?if !(hFamily && hFont && hFormat && pBrush && pGraphics)
??return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
??
?CreateRectF(RC, xpos, ypos, Width, Height)
?Gdip_SetStringFormatAlign(hFormat, Align)
?Gdip_SetTextRenderingHint(pGraphics, Rendering)
?ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)

?if vPos
?{
??StringSplit, ReturnRC, ReturnRC, |
??
??if (vPos = "vCentre") || (vPos = "vCenter")
???ypos += (Height-ReturnRC4)//2
??else if (vPos = "Top") || (vPos = "Up")
???ypos := 0
??else if (vPos = "Bottom") || (vPos = "Down")
???ypos := Height-ReturnRC4
??
??CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
??ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
?}

?if !Measure
??E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)

?if !PassBrush
??Gdip_DeleteBrush(pBrush)
?Gdip_DeleteStringFormat(hFormat)??
?Gdip_DeleteFont(hFont)
?Gdip_DeleteFontFamily(hFamily)
?return E ? E : ReturnRC
}

;#####################################################################################

Gdip_DrawString(pGraphics, sString, hFont, hFormat, pBrush, ByRef RectF)
{
?if !A_IsUnicode
?{
??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)
??return DllCall("gdiplus\GdipDrawString", "uint", pGraphics
??, "uint", &wString, "int", -1, "uint", hFont, "uint", &RectF, "uint", hFormat, "uint", pBrush)
?}
?else
?{
??return DllCall("gdiplus\GdipDrawString", "uint", pGraphics
??, "uint", &sString, "int", -1, "uint", hFont, "uint", &RectF, "uint", hFormat, "uint", pBrush)
?}?
}

;#####################################################################################

Gdip_MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF)
{
?VarSetCapacity(RC, 16)
?if !A_IsUnicode
?{
??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\GdipMeasureString", "uint", pGraphics
??, "uint", &wString, "int", -1, "uint", hFont, "uint", &RectF, "uint", hFormat, "uint", &RC, "uint*", Chars, "uint*", Lines)
?}
?else
?{
??DllCall("gdiplus\GdipMeasureString", "uint", pGraphics
??, "uint", &sString, "int", -1, "uint", hFont, "uint", &RectF, "uint", hFormat, "uint", &RC, "uint*", Chars, "uint*", Lines)
?}
?return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
}

; Near = 0
; Center = 1
; Far = 2
Gdip_SetStringFormatAlign(hFormat, Align)
{
?? return DllCall("gdiplus\GdipSetStringFormatAlign", "uint", hFormat, "int", Align)
}

; StringFormatFlagsDirectionRightToLeft??? = 0x00000001
; StringFormatFlagsDirectionVertical?????? = 0x00000002
; StringFormatFlagsNoFitBlackBox?????????? = 0x00000004
; StringFormatFlagsDisplayFormatControl??? = 0x00000020
; StringFormatFlagsNoFontFallback????????? = 0x00000400
; StringFormatFlagsMeasureTrailingSpaces?? = 0x00000800
; StringFormatFlagsNoWrap????????????????? = 0x00001000
; StringFormatFlagsLineLimit?????????????? = 0x00002000
; StringFormatFlagsNoClip????????????????? = 0x00004000
Gdip_StringFormatCreate(Format=0, Lang=0)
{
?? DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", Lang, "uint*", hFormat)
?? return hFormat
}

; Regular = 0
; Bold = 1
; Italic = 2
; BoldItalic = 3
; Underline = 4
; Strikeout = 8
Gdip_FontCreate(hFamily, Size, Style=0)
{
?? DllCall("gdiplus\GdipCreateFont", "uint", hFamily, "float", Size, "int", Style, "int", 0, "uint*", hFont)
?? return hFont
}

Gdip_FontFamilyCreate(Font)
{
?if !A_IsUnicode
?{
??nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, "uint", &Font, "int", -1, "uint", 0, "int", 0)
??VarSetCapacity(wFont, nSize*2)
??DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, "uint", &Font, "int", -1, "uint", &wFont, "int", nSize)
??DllCall("gdiplus\GdipCreateFontFamilyFromName", "uint", &wFont, "uint", 0, "uint*", hFamily)
?}
?else
??DllCall("gdiplus\GdipCreateFontFamilyFromName", "uint", &Font, "uint", 0, "uint*", hFamily)
?return hFamily
}

;#####################################################################################
; Matrix functions
;#####################################################################################

Gdip_CreateAffineMatrix(m11, m12, m21, m22, x, y)
{
?? DllCall("gdiplus\GdipCreateMatrix2", "float", m11, "float", m12, "float", m21, "float", m22, "float", x, "float", y, "uint*", Matrix)
?? return Matrix
}

Gdip_CreateMatrix()
{
?? DllCall("gdiplus\GdipCreateMatrix", "uint*", Matrix)
?? return Matrix
}

;#####################################################################################
; GraphicsPath functions
;#####################################################################################

; Alternate = 0
; Winding = 1
Gdip_CreatePath(BrushMode=0)
{
?DllCall("gdiplus\GdipCreatePath", "int", BrushMode, "uint*", Path)
?return Path
}

Gdip_AddPathEllipse(Path, x, y, w, h)
{
?return DllCall("gdiplus\GdipAddPathEllipse", "uint", Path, "float", x, "float", y, "float", w, "float", h)
}

Gdip_AddPathPolygon(Path, 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\GdipAddPathPolygon", "uint", Path, "uint", &PointF, "int", Points0)
}

Gdip_DeletePath(Path)
{
?return DllCall("gdiplus\GdipDeletePath", "uint", Path)
}

;#####################################################################################
; Quality functions
;#####################################################################################

; SystemDefault = 0
; SingleBitPerPixelGridFit = 1
; SingleBitPerPixel = 2
; AntiAliasGridFit = 3
; AntiAlias = 4
Gdip_SetTextRenderingHint(pGraphics, RenderingHint)
{
?return DllCall("gdiplus\GdipSetTextRenderingHint", "uint", pGraphics, "int", RenderingHint)
}

; Default = 0
; LowQuality = 1
; HighQuality = 2
; Bilinear = 3
; Bicubic = 4
; NearestNeighbor = 5
; HighQualityBilinear = 6
; HighQualityBicubic = 7
Gdip_SetInterpolationMode(pGraphics, InterpolationMode)
{
?? return DllCall("gdiplus\GdipSetInterpolationMode", "uint", pGraphics, "int", InterpolationMode)
}

; Default = 0
; HighSpeed = 1
; HighQuality = 2
; None = 3
; AntiAlias = 4
Gdip_SetSmoothingMode(pGraphics, SmoothingMode)
{
?? return DllCall("gdiplus\GdipSetSmoothingMode", "uint", pGraphics, "int", SmoothingMode)
}

; CompositingModeSourceOver = 0 (blended)
; CompositingModeSourceCopy = 1 (overwrite)
Gdip_SetCompositingMode(pGraphics, CompositingMode=0)
{
?? return DllCall("gdiplus\GdipSetCompositingMode", "uint", pGraphics, "int", CompositingMode)
}

;#####################################################################################
; Extra functions
;#####################################################################################

Gdip_Startup()
{
?if !DllCall("GetModuleHandle", "str", "gdiplus")
??DllCall("LoadLibrary", "str", "gdiplus")
?VarSetCapacity(si, 16, 0), si := Chr(1)
?DllCall("gdiplus\GdiplusStartup", "uint*", pToken, "uint", &si, "uint", 0)
?return pToken
}

Gdip_Shutdown(pToken)
{
?DllCall("gdiplus\GdiplusShutdown", "uint", pToken)
?if hModule := DllCall("GetModuleHandle", "str", "gdiplus")
??DllCall("FreeLibrary", "uint", hModule)
?return 0
}

; Prepend = 0; The new operation is applied before the old operation.
; Append = 1; The new operation is applied after the old operation.
Gdip_RotateWorldTransform(pGraphics, Angle, MatrixOrder=0)
{
?return DllCall("gdiplus\GdipRotateWorldTransform", "uint", pGraphics, "float", Angle, "int", MatrixOrder)
}

Gdip_ScaleWorldTransform(pGraphics, x, y, MatrixOrder=0)
{
?return DllCall("gdiplus\GdipScaleWorldTransform", "uint", pGraphics, "float", x, "float", y, "int", MatrixOrder)
}

Gdip_TranslateWorldTransform(pGraphics, x, y, MatrixOrder=0)
{
?return DllCall("gdiplus\GdipTranslateWorldTransform", "uint", pGraphics, "float", x, "float", y, "int", MatrixOrder)
}

Gdip_ResetWorldTransform(pGraphics)
{
?return DllCall("gdiplus\GdipResetWorldTransform", "uint", pGraphics)
}

Gdip_GetRotatedTranslation(Width, Height, Angle, ByRef xTranslation, ByRef yTranslation)
{
?pi := 3.14159, TAngle := Angle*(pi/180)?

?Bound := (Angle >= 0) ? Mod(Angle, 360) : 360-Mod(-Angle, -360)
?if ((Bound >= 0) && (Bound <= 90))
??xTranslation := Height*Sin(TAngle), yTranslation := 0
?else if ((Bound > 90) && (Bound <= 180))
??xTranslation := (Height*Sin(TAngle))-(Width*Cos(TAngle)), yTranslation := -Height*Cos(TAngle)
?else if ((Bound > 180) && (Bound <= 270))
??xTranslation := -(Width*Cos(TAngle)), yTranslation := -(Height*Cos(TAngle))-(Width*Sin(TAngle))
?else if ((Bound > 270) && (Bound <= 360))
??xTranslation := 0, yTranslation := -Width*Sin(TAngle)
}

Gdip_GetRotatedDimensions(Width, Height, Angle, ByRef RWidth, ByRef RHeight)
{
?pi := 3.14159, TAngle := Angle*(pi/180)
?if !(Width && Height)
??return -1
?RWidth := Ceil(Abs(Width*Cos(TAngle))+Abs(Height*Sin(TAngle)))
?RHeight := Ceil(Abs(Width*Sin(TAngle))+Abs(Height*Cos(Tangle)))
}

; RotateNoneFlipNone?? = 0
; Rotate90FlipNone???? = 1
; Rotate180FlipNone??? = 2
; Rotate270FlipNone??? = 3
; RotateNoneFlipX????? = 4
; Rotate90FlipX??????? = 5
; Rotate180FlipX?????? = 6
; Rotate270FlipX?????? = 7
; RotateNoneFlipY????? = Rotate180FlipX
; Rotate90FlipY??????? = Rotate270FlipX
; Rotate180FlipY?????? = RotateNoneFlipX
; Rotate270FlipY?????? = Rotate90FlipX
; RotateNoneFlipXY???? = Rotate180FlipNone
; Rotate90FlipXY?????? = Rotate270FlipNone
; Rotate180FlipXY????? = RotateNoneFlipNone
; Rotate270FlipXY????? = Rotate90FlipNone

Gdip_ImageRotateFlip(pBitmap, RotateFlipType=1)
{
?return DllCall("gdiplus\GdipImageRotateFlip", "uint", pBitmap, "int", RotateFlipType)
}

; Replace = 0
; Intersect = 1
; Union = 2
; Xor = 3
; Exclude = 4
; Complement = 5
Gdip_SetClipRect(pGraphics, x, y, w, h, CombineMode=0)
{
?? return DllCall("gdiplus\GdipSetClipRect", "uint", pGraphics, "float", x, "float", y, "float", w, "float", h, "int", CombineMode)
}

Gdip_SetClipPath(pGraphics, Path, CombineMode=0)
{
?? return DllCall("gdiplus\GdipSetClipPath", "uint", pGraphics, "uint", Path, "int", CombineMode)
}

Gdip_ResetClip(pGraphics)
{
?? return DllCall("gdiplus\GdipResetClip", "uint", pGraphics)
}

Gdip_GetClipRegion(pGraphics)
{
?Region := Gdip_CreateRegion()
?DllCall("gdiplus\GdipGetClip", "uint" pGraphics, "uint*", Region)
?return Region
}

Gdip_SetClipRegion(pGraphics, Region, CombineMode=0)
{
?return DllCall("gdiplus\GdipSetClipRegion", "uint", pGraphics, "uint", Region, "int", CombineMode)
}

Gdip_CreateRegion()
{
?DllCall("gdiplus\GdipCreateRegion", "uint*", Region)
?return Region
}

Gdip_DeleteRegion(Region)
{
?return DllCall("gdiplus\GdipDeleteRegion", "uint", Region)
}

;#####################################################################################
; BitmapLockBits
;#####################################################################################

Gdip_LockBits(pBitmap, x, y, w, h, ByRef Stride, ByRef Scan0, ByRef BitmapData, LockMode = 3, PixelFormat = 0x26200a)
{??
?CreateRect(Rect, x, y, w, h)
?VarSetCapacity(BitmapData, 21, 0)
?E := DllCall("Gdiplus\GdipBitmapLockBits", "uint", pBitmap, "uint", &Rect, "uint", LockMode, "int", PixelFormat, "uint", &BitmapData)
?Stride := NumGet(BitmapData, 8)
?Scan0 := NumGet(BitmapData, 16)
?return E
}

;#####################################################################################

Gdip_UnlockBits(pBitmap, ByRef BitmapData)
{
?return DllCall("Gdiplus\GdipBitmapUnlockBits", "uint", pBitmap, "uint", &BitmapData)
}

;#####################################################################################

Gdip_SetLockBitPixel(ARGB, Scan0, x, y, Stride)
{
?Numput(ARGB, Scan0+0, (x*4)+(y*Stride))
}

;#####################################################################################

Gdip_GetLockBitPixel(Scan0, x, y, Stride)
{
?return NumGet(Scan0+0, (x*4)+(y*Stride))
}

;#####################################################################################

Gdip_PixelateBitmap(pBitmap, ByRef pBitmapOut, BlockSize)
{
?static PixelateBitmap
?if !PixelateBitmap
?{
??MCode_PixelateBitmap := "83EC388B4424485355568B74245C99F7FE8B5C244C8B6C2448578BF88BCA894C241C897C243485FF0F8E2E0300008B44245"
??. "499F7FE897C24448944242833C089542418894424308944242CEB038D490033FF397C2428897C24380F8E750100008BCE0FAFCE894C24408DA4240000"
??. "000033C03BF08944241089442460894424580F8E8A0000008B5C242C8D4D028BD52BD183C203895424208D3CBB0FAFFE8BD52BD142895424248BD52BD"
??. "103F9897C24148974243C8BCF8BFE8DA424000000008B5C24200FB61C0B03C30FB619015C24588B5C24240FB61C0B015C24600FB61C11015C241083C1"
??. "0483EF0175D38B7C2414037C245C836C243C01897C241475B58B7C24388B6C244C8B5C24508B4C244099F7F9894424148B44245899F7F9894424588B4"
??. "4246099F7F9894424608B44241099F7F98944241085F60F8E820000008D4B028BC32BC18D68038B44242C8D04B80FAFC68BD32BD142895424248BD32B"
??. "D103C18944243C89742420EB038D49008BC88BFE0FB64424148B5C24248804290FB644245888010FB644246088040B0FB644241088040A83C10483EF0"
??. "175D58B44243C0344245C836C2420018944243C75BE8B4C24408B5C24508B6C244C8B7C2438473B7C2428897C24380F8C9FFEFFFF8B4C241C33D23954"
??. "24180F846401000033C03BF2895424108954246089542458895424148944243C0F8E82000000EB0233D2395424187E6F8B4C243003C80FAF4C245C8B4"
??. "424280FAFC68D550203CA8D0C818BC52BC283C003894424208BC52BC2408BFD2BFA8B54241889442424895424408B4424200FB614080FB60101542414"
??. "8B542424014424580FB6040A0FB61439014424600154241083C104836C24400175CF8B44243C403BC68944243C7C808B4C24188B4424140FAFCE99F7F"
??. "9894424148B44245899F7F9894424588B44246099F7F9894424608B44241099F7F98944241033C08944243C85F60F8E7F000000837C2418007E6F8B4C"
??. "243003C80FAF4C245C8B4424280FAFC68D530203CA8D0C818BC32BC283C003894424208BC32BC2408BFB2BFA8B54241889442424895424400FB644241"
??. "48B5424208804110FB64424580FB654246088018B4424248814010FB654241088143983C104836C24400175CF8B44243C403BC68944243C7C818B4C24"
??. "1C8B44245C0144242C01742430836C2444010F85F4FCFFFF8B44245499F7FE895424188944242885C00F8E890100008BF90FAFFE33D2897C243C89542"
??. "45489442438EB0233D233C03BCA89542410895424608954245889542414894424400F8E840000003BF27E738B4C24340FAFCE03C80FAF4C245C034C24"
??. "548D55028BC52BC283C003894424208BC52BC2408BFD03CA894424242BFA89742444908B5424200FB6040A0FB611014424148B442424015424580FB61"
??. "4080FB6040F015424600144241083C104836C24440175CF8B4424408B7C243C8B4C241C33D2403BC1894424400F8C7CFFFFFF8B44241499F7FF894424"
??. "148B44245899F7FF894424588B44246099F7FF894424608B44241099F7FF8944241033C08944244085C90F8E8000000085F67E738B4C24340FAFCE03C"
??. "80FAF4C245C034C24548D53028BC32BC283C003894424208BC32BC2408BFB03CA894424242BFA897424448D49000FB65424148B4424208814010FB654"
??. "24580FB644246088118B5424248804110FB644241088043983C104836C24440175CF8B4424408B7C243C8B4C241C403BC1894424407C808D04B500000"
??. "00001442454836C2438010F858CFEFFFF33D233C03BCA89542410895424608954245889542414894424440F8E9A000000EB048BFF33D2395424180F8E"
??. "7D0000008B4C24340FAFCE03C80FAF4C245C8B4424280FAFC68D550203CA8D0C818BC52BC283C003894424208BC52BC240894424248BC52BC28B54241"
??. "8895424548DA424000000008B5424200FB6140A015424140FB611015424588B5424240FB6140A015424600FB614010154241083C104836C24540175CF"
??. "8B4424448B4C241C403BC1894424440F8C6AFFFFFF0FAF4C24188B44241499F7F9894424148B44245899F7F9894424588B44246099F7F9894424608B4"
??. "4241099F7F98944241033C03944241C894424540F8E7B0000008B7C241885FF7E688B4C24340FAFCE03C80FAF4C245C8B4424280FAFC68D530203CA8D"
??. "0C818BC32BC283C003894424208BC32BC2408BEB894424242BEA0FB65424148B4424208814010FB65424580FB644246088118B5424248804110FB6442"
??. "41088042983C10483EF0175D18B442454403B44241C894424547C855F5E5D33C05B83C438C3"
??VarSetCapacity(PixelateBitmap, StrLen(MCode_PixelateBitmap)//2)
??Loop % StrLen(MCode_PixelateBitmap)//2??;%
???NumPut("0x" SubStr(MCode_PixelateBitmap, (2*A_Index)-1, 2), PixelateBitmap, A_Index-1, "char")
?}

?Gdip_GetImageDimensions(pBitmap, Width, Height)
?if (Width != Gdip_GetImageWidth(pBitmapOut) || Height != Gdip_GetImageHeight(pBitmapOut))
??return -1
?if (BlockSize > Width || BlockSize > Height)
??return -2

?E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1)
?E2 := Gdip_LockBits(pBitmapOut, 0, 0, Width, Height, Stride2, Scan02, BitmapData2)
?if (E1 || E2)
??return -3

?E := DllCall(&PixelateBitmap, "uint", Scan01, "uint", Scan02, "int", Width, "int", Height, "int", Stride1, "int", BlockSize)
?Gdip_UnlockBits(pBitmap, BitmapData1), Gdip_UnlockBits(pBitmapOut, BitmapData2)
?return 0
}

;#####################################################################################

Gdip_ToARGB(A, R, G, B)
{
?return (A << 24) | (R << 16) | (G << 8) | B
}

;#####################################################################################

Gdip_FromARGB(ARGB, ByRef A, ByRef R, ByRef G, ByRef B)
{
?A := (0xff000000 & ARGB) >> 24
?R := (0x00ff0000 & ARGB) >> 16
?G := (0x0000ff00 & ARGB) >> 8
?B := 0x000000ff & ARGB
}

;#####################################################################################

Gdip_AFromARGB(ARGB)
{
?return (0xff000000 & ARGB) >> 24
}

;#####################################################################################

Gdip_RFromARGB(ARGB)
{
?return (0x00ff0000 & ARGB) >> 16
}

;#####################################################################################

Gdip_GFromARGB(ARGB)
{
?return (0x0000ff00 & ARGB) >> 8
}

;#####################################################################################

Gdip_BFromARGB(ARGB)
{
?return 0x000000ff & ARGB
}


  • profile
    외치기 2015.04.16 09:15

    클립보드에 있는 이미지를 가져와서 비교하는데 어떻게 가려진창도 스캔 할 수 있는거죠?

  • 암드래 2015.04.16 12:13

    아 설명을 잘못했네요, 가려진 창으로부터 프린트 스크린을 통해 이미지를 클립보드에 저장시킨 뒤,

    이를 서치한다는 내용입니다^^ 본문, 제목 수정했습니다.

  • 매크로맨서 2015.04.16 13:29

    가려진 창으로부터 프린트스크린을 하려면 postmessage 같은것을 이용하신다는 말씀인가요


    찾아보니 가능하군요 pm으로 wm_paint 같은걸 보내면..

    근데 어차피 그러면 bitmapfromhwnd와 다를게 없어지는거 같네요

  • 암드래 2015.04.16 15:13
    예, 그런데 bitmapfromhwnd 같은 경우에는 프로텍터가 있는 응용 프로그램에서는

    쓸수가 없으니, 그나마 대안으로 생각해본 방법이었습니다. 다만, 이것도 프린트키가 먹힌다는 조건이

    있어야 하지만요
  • 매크로맨서 2015.04.17 01:27
    그러네요 일단 wm_paint 도 염두해봐야겠군요
  • minixb 2015.04.18 17:34

    감사합니다. 연구가 필요하네요...ㅜㅜㅜ

  • 열감기 2015.06.16 11:44

    감사합니다..

  • Muchi 2015.07.12 11:13

    감사합니다.

  • 진진돌이 2015.07.16 12:55

    죄송한데 강제디컴좀도와주실수있나요 악용하려는건아니고 유료프로그램을샀는데 판매자가 도망가버리고 인증을끊어버렸네요 진짜괘씸한데 댓글보다가 강제디컴하실줄아신다길래 이렇게 염치불구하고 도움요청해봅니다..

  • bellms 2016.03.30 10:10
    가려진 창을 어떻게 프린트키로 클립보드로 보내는 거죠??
  • 제이아이에이 2016.07.19 12:07

    감사합니다


List of Articles
분류 제목 글쓴이 최근변경 추천
정보 (안내) 글내용확인하시고 자삭하세요 27 snf 2015.02.23 0/0
정보 (펌)픽셀서치를 대체할 수 있는 비활성픽셀칼라 활용 ... 6 앙꼬호빵 2019.05.26 0/0
정보 adb 관련 비활성화 이미지 서치 쉽게하기 6 운하파는 2016.07.02 1/0
정보 adb를 이용한 연속 터치 및 키입력 TIP 7 하연데디 2019.03.05 1/0
정보 AHK_Helper.exe 오토핫키 도움말 프로그램 입니다. 2 월드걸스 2023.02.24 0/0
정보 Array 확장 13 모바게 2015.07.16 3/0
정보 Autohotkey에서 함수와 ByRef 사용에 대해... 12 류Macro 2015.07.12 1/0
정보 ControlSend 명령을 이용한, 카톡으로 알림받기 간단하... 10 죠케빈 2018.01.02 0/0
정보 DllCall "mouse_event" 속도조절하는 법 rkfdma 2016.12.08 0/0
정보 DynaScript - Child 프로세스로 코드 실행 13 예지력1 2019.07.16 3/0
정보 gdip 간단 응용 팁들 13 매크로맨서 2015.04.18 0/0
정보 gdip 비활성 이미지 서치, postmessage 모모 소스입니다. 6 사이다업 2021.01.23 1/0
정보 Gdip_all.ahk를 이용한 Bitmap의 size 변경 함수 6 할거엄따구 2022.12.14 1/0
정보 Gdip를 이용한 클립보드에 있는 이미지를 통한 이미지서치 11 암드래 2016.07.19 0/0
정보 GUI - 파일(폴더) 목록을 DropDownList로 만들기 14 모바게 2016.06.13 3/0
정보 Gui- dropdownlist 사용하기 기초내용 (모르시는 분만 ... 3 으뜸어린이 2017.09.07 1/0
정보 g라벨? v라벨? 설명좀해주세요 5 이리오리오 2016.10.25 0/0
정보 INI 를 쉽게 사용해봅시다. 11 모바게 2017.11.01 3/0
정보 ListBox로 로그창을 만들어보자! 고음l 2017.11.18 1/0
정보 List에 해당하는 GUI 팁 9 외치기 2015.08.24 2/0
Board Pagination Prev 1 23456 7 Next
/ 7

전체 최신 인기글

전체 주간 인기글