Carcophan:
If you will only need to alter the image a small number of times then Tutorial 9 is still applicable. It would be done in exactly the same way. Draw your graph into a pBitmap and SetImage a converted hBitmap to the hwnd of your control/window. If it will be updated many times then create a gdi bitmap and continually bitblt its hdc into the hwnd of the control/window.
You can see a similar use of it in my post here:
http://www.autohotkey.com/forum/viewtopic.php?t=59265
(I stole Zaelia's elasticity formula)
Lucid_Method:
Glad you like the examples

I really wish I could devote more time and write more....
Well....It can be done in ahk as seen below, however, it is quite slow. I tried spaghetti coding it a little bit to speed it up, but it didnt make too much difference. Its not super slow though, but I would need to rewrite it in c++ and compile to machine code. I'll write the machine code equivalent as I think it would be a nice addition. Im still thinking how best to go about adding lockbits to the library.....anyone have any comments on how it currently looks?
Code:
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
OnExit, Exit
pBitmapHayStack := Gdip_CreateBitmapFromFile("ImageHayStack.png")
pBitmapNeedle := Gdip_CreateBitmapFromFile("ImageNeedle.png")
Time1 := A_TickCount
Coords := SlowImageSearch(pBitmapHayStack, pBitmapNeedle)
MsgBox, % A_TIckCount-Time1 "`n" Coords ;%
Gdip_DisposeImage(pBitmapHayStack), Gdip_DisposeImage(pBitmapNeedle)
return
;#######################################################################
SlowImageSearch(pBitmapHayStack, pBitmapNeedle)
{
Width1 := Gdip_GetImageWidth(pBitmapHayStack), Height1 := Gdip_GetImageHeight(pBitmapHayStack)
Width2 := Gdip_GetImageWidth(pBitmapNeedle), Height2 := Gdip_GetImageHeight(pBitmapNeedle)
E1 := Gdip_LockBits(pBitmapHayStack, 0, 0, Width1, Height1, Stride1, Scan01)
E2 := Gdip_LockBits(pBitmapNeedle, 0, 0, Width2, Height2, Stride2, Scan02)
p := Gdip_GetLockBitPixel(Scan02, 0, 0, Stride2)
y1 := 0
Loop, %Height1%
{
Loop, %Width1%
{
x1 := A_Index-1, y2 := 0, yt := y1
Match := 1
Loop, %Height2%
{
xt := x1
if (A_Index = 1)
{
if (Gdip_GetLockBitPixel(Scan01, ++xt, yt, Stride1) != p)
{
Match := 0
GoTo, NoMatch
}
}
else
{
Loop, %Width2%
{
if (Gdip_GetLockBitPixel(Scan01, ++xt, yt, Stride1) != Gdip_GetLockBitPixel(Scan02, A_Index-1, y2, Stride2))
{
Match := 0
GoTo, NoMatch
}
}
}
y2++, yt++
}
if Match
GoTo, Match
NoMatch:
continue
}
y1++
}
Match:
Gdip_UnlockBits(pBitmapHayStack), Gdip_UnlockBits(pBitmapNeedle)
return Match ? xt-Width2 "|" yt-Height2 : 0
}
;#######################################################################
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")
}
;#######################################################################
Gdip_LockBits(pBitmap, x, y, w, h, ByRef Stride, ByRef Scan0, 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)
{
return DllCall("Gdiplus\GdipBitmapUnlockBits", "uint", pBitmap, "uint", &BitmapData)
}
;#######################################################################
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
}
;#######################################################################
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))
}
;#######################################################################
Exit:
Gdip_Shutdown(pToken)
ExitApp
return
edit:
added
Code:
p := Gdip_GetLockBitPixel(Scan02, 0, 0, Stride2)
for a bit more speed