ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
-
- Posts: 941
- Joined: 30 Sep 2017, 03:59
- Location: Romania
- Contact:
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
@iseahound .impressive work!
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
KeyPress OSD v4: GitHub or forum. (presentation video)
Quick Picto Viewer: GitHub or forum.
AHK GDI+ expanded / compilation library (on GitHub)
My home page.
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Hey!
I want to take a screenshot and run an imagesearch on it from a Application thats not currently in the foreground/ covered by other applications.
how to do used imageput ()?
=========================================================
=======================================================================
I want to take a screenshot and run an imagesearch on it from a Application thats not currently in the foreground/ covered by other applications.
how to do used imageput ()?
Code: Select all
; 窗口类
ImagePutWindow("ahk_class notepad")
Code: Select all
Error: Image type could not be identified.
---- d:\LibV2\ImagePut.ah2
565: If ComObjQuery(image, "{A2296057-EA42-4099-983B-539FB6505426}")
566: Return "D2dBitmap"
▶ 569: Throw Error("Image type could not be identified.")
570: }
572: {
The current thread will exit.
Code: Select all
; 或将类型声明为截屏:
ImagePutWindow({screenshot: "Untitled - Notepad", crop: [0, 0, 100, 100]}) ; 使用 BitBlt 进行屏幕捕捉
Code: Select all
Error: This value of type "String" has no method named "Has".
---- d:\LibV2\ImagePut.ah2
1422: image := [x, y, w, h]
1423: }
▶ 1429: If image.Has(5) and WinExist(image[5])
1429: {
1430: Try
Code: Select all
; 或将类型声明为截屏:
ImagePutWindow({window: "Untitled - Notepad", crop: [0, 0, 100, 100]}) ; 使用 PrintWindow 进行窗口捕获
Code: Select all
Error: pBitmap cannot be zero.
---- d:\LibV2\ImagePut.ah2
314: cleanup := "stream"
318: If !(pBitmap := this.ImageToBitmap(type, image, keywords))
▶ 319: Throw Error("pBitmap cannot be zero.")
323: (validate) && DllCall("gdiplus\GdipImageForceValidation", "ptr", pBitmap)
324: (crop) && this.BitmapCrop(&pBitmap, crop)
The current thread will exit.
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
That's not me... WinExist() is case sensitive. Try ahk_class Notepad on Windows 11. I think before, it used to be lowercase on Windows 7 and I never changed the documentation.
-
- Posts: 7
- Joined: 21 Jun 2024, 12:43
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Thanks for the awesome script iseahound.
I was hoping someone could help me with ImageSearch function in it. I'm able to get it to successfully recognize images if I just feed it an image path for matching. However, I'd like to add a variation allowance but if I feed it a variation amount it seems to always give a match with the top left of my display if the match isn't found.
This seems like it must be a bug but I could also be doing something wrong. Below is the code I've been using for testing this.
This Works
This always gives a match (top left) even if the image is not on the screen.
Thanks in advance for any help.
I was hoping someone could help me with ImageSearch function in it. I'm able to get it to successfully recognize images if I just feed it an image path for matching. However, I'd like to add a variation allowance but if I feed it a variation amount it seems to always give a match with the top left of my display if the match isn't found.
This seems like it must be a bug but I could also be doing something wrong. Below is the code I've been using for testing this.
This Works
Code: Select all
x::
{
pic := ImagePutBuffer(0)
If pic.ImageSearch("C:\Users\User\Desktop\test.png")
MsgBox "Test"
}
Code: Select all
pic := ImagePutBuffer(0)
If xy := pic.ImageSearch("C:\Users\User\Desktop\test.png", 30)
MouseMove xy[1], xy[2]
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
While the PixelSearch module is fully complete, the ImageSearch module might be a little bugged. I should probably review the code and release the next version of ImagePut already. Would you be willing to help test benchmarks and changes?
-
- Posts: 7
- Joined: 21 Jun 2024, 12:43
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
@iseahound
Sure I'd be happy to help test.
Sure I'd be happy to help test.
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
I know this isn't ImageSearch, but I need testers for multithreading (yes, this is real OS level threads) when saving files to disk.
@sushibagel Would you be able to help with this?
Anyone is free to test this. I'm looking for a good default number of threads to use, but I don't have large number of computers to test this on. A zip file is included to make things easier to test. The purpose of this is to increase the screen capture and save to file frame rate to over 60 fps. Eskitit!!!!!
@sushibagel Would you be able to help with this?
Code: Select all
#include ImagePut.ahk
thread_count := InputBox("Number of OS level threads to use:",,, 8).Value
buf := ImagePutBuffer(f := FileSelect())
extension := "png" ; try "jpg" or "bmp"
try DirDelete("yyy", 1)
try DirDelete("zzz", 1)
n := 100
DllCall("QueryPerformanceFrequency", "int64*", &frequency:=0)
DllCall("QueryPerformanceCounter", "int64*", &start:=0)
loop n
ImagePut.BitmapToFile(buf.pBitmap, "yyy\1." extension)
DllCall("QueryPerformanceCounter", "int64*", &end:=0)
a := n / ((end - start) / frequency)
DllCall("QueryPerformanceCounter", "int64*", &start:=0)
loop n
fn2(buf, "zzz\" A_Index "." extension)
DllCall("QueryPerformanceCounter", "int64*", &end:=0)
b := n / ((end - start) / frequency)
last_file := "zzz\" n "." extension
;MsgBox FileExist(last_file) ? "Exists" : "Doesn't exist"
;MsgBox s
MsgBox "BitmapToFile:`t`t" Round(a, 2) " fps"
. "`nThread Pool:`t`t" Round(b, 2) " fps"
. "`nNumber of Threads:`t`t" thread_count
. "`nConvert Extension:`t`t" extension
. "`nFrames per second (Higher is better)"
, f
fn(clone, &filepath, &pCodec, &ep, &hThread) {
pBitmap := clone.pBitmap
extension := "png"
quality := ""
ImagePut.select_filepath(&filepath, &extension)
ImagePut.select_codec(pBitmap, extension, quality, &pCodec, &ep)
pcb := callback(pBitmap, &filepath, pCodec, ep)
;DllCall(pcb)
hThread := DllCall("CreateThread", "ptr", 0, "ptr", 0, "ptr", pcb, "ptr", 456, "uint", 0, "uint*", 0, "ptr")
; Export objects to manage lifetimes.
return
}
fn2(buf, filepath2) {
clone := buf.Clone()
pCodec := &pCodec
ep := &ep
filepath := &filepath2
hThread := &hThread2
static queue := []
fn(clone, filepath, pCodec, ep, hThread)
if queue.length >= thread_count {
c := queue.RemoveAt(1)
check := %c.hThread%
start := A_TickCount
DllCall("WaitForSingleObject", "ptr", check, "uint", 0xFFFFFFFF)
global s .= "`n" A_TickCount - start
; lifetimes eliminated here.
}
if filepath2 ~= "^zzz\\" n {
for c in queue
DllCall("WaitForSingleObject", "ptr", %c.hThread%, "uint", 0xFFFFFFFF)
}
continuation := {
clone: clone,
pCodec: pCodec,
ep: ep,
filepath: filepath,
hThread: hThread,
__Delete: (self) => Tooltip(%self.filepath%)
}
queue.push(continuation)
}
Esc:: Reload
;DllCall(pcb)
;DllCall(GdipSaveImageToFile, "ptr", pBitmap, "wstr", filepath, "ptr", pCodec, "ptr", ep)
callback( pBitmap, &filepath, pCodec, ep) {
gdiplus := DllCall("GetModuleHandle", "str", "gdiplus.dll", "ptr")
GdipSaveImageToFile := DllCall("GetProcAddress", "ptr", gdiplus, "astr", "GdipSaveImageToFile", "ptr")
ncb := (A_PtrSize = 4) ? 28 : 81
pcb := DllCall("GlobalAlloc", "uint", 0, "uptr", ncb, "ptr")
DllCall("VirtualProtect", "ptr", pcb, "ptr", ncb, "uint", 0x40, "uint*", 0)
; Retract the hex representation to binary.
;if (A_PtrSize = 8) {
assembly := "
( Join`s Comments
48 89 4c 24 08 ; 0: mov [rsp+8], rcx
48 89 54 24 10 ; 5: mov [rsp+16], rdx
4c 89 44 24 18 ; 10: mov [rsp+24], r8
4c 89 4c 24 20 ; 15: mov [rsp+32], r9
48 83 ec 28 ; 20: sub rsp, 40
49 b9 00 00 00 00 00 00 00 00 ; 24: mov r9, .. (ep)
49 b8 00 00 00 00 00 00 00 00 ; 34: mov r8, .. (pCodec)
48 ba 00 00 00 00 00 00 00 00 ; 44: mov edx, .. (&filepath)
48 b9 00 00 00 00 00 00 00 00 ; 54: mov ecx, .. (pBitmap)
48 b8 00 00 00 00 00 00 00 00 ; 64: mov rax, .. (GdipSaveImageToFile)
ff d0 ; 74: call rax
48 83 c4 28 ; 76: add rsp, 40
c3 ; 80: ret
)" ; 81:
DllCall("crypt32\CryptStringToBinary", "str", assembly, "uint", 0, "uint", 0x4, "ptr", pcb, "uint*", ncb, "ptr", 0, "ptr", 0)
NumPut("ptr", GdipSaveImageToFile, pcb + 66)
NumPut("ptr", pBitmap, pcb + 56)
NumPut("ptr", StrPtr(filepath), pcb + 46)
NumPut("ptr", pCodec.ptr, pcb + 36)
NumPut("ptr", ep, pcb + 26)
/*
}
else {
assembly := "
( Join`s Comments
68 00 00 00 00 ; push .. (lParam)
68 00 00 00 00 ; push .. (wParam)
68 00 00 00 00 ; push .. (uMsg)
68 00 00 00 00 ; push .. (hwnd)
b8 00 00 00 00 ; mov eax, .. (SendMessageW)
ff d0 ; call eax
c3 ; ret
)"
DllCall("crypt32\CryptStringToBinary", "str", assembly, "uint", 0, "uint", 0x4, "ptr", pcb, "uint*", ncb, "ptr", 0, "ptr", 0)
NumPut("int", SendMessageW, pcb + 21)
NumPut("int", hwnd, pcb + 16)
NumPut("int", uMsg, pcb + 11)
NumPut("int", wParam, pcb + 6)
NumPut("int", lParam, pcb + 1)
}
*/
; return pcb
return pcb
}
- Attachments
-
- Save Image To File (multi-threaded).zip
- (59.32 KiB) Downloaded 54 times
-
- Posts: 7
- Joined: 21 Jun 2024, 12:43
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Ran it twice. First time was while my laptop was running on battery with a lower performance mode (53 FPS), second time while plugged in (119 FPS).iseahound wrote: ↑04 Jul 2024, 16:30I know this isn't ImageSearch, but I need testers for multithreading (yes, this is real OS level threads) when saving files to disk.
@sushibagel Would you be able to help with this?
Anyone is free to test this. I'm looking for a good default number of threads to use, but I don't have large number of computers to test this on. A zip file is included to make things easier to test. The purpose of this is to increase the screen capture and save to file frame rate to over 60 fps. Eskitit!!!!!Code: Select all
#include ImagePut.ahk thread_count := InputBox("Number of OS level threads to use:",,, 8).Value buf := ImagePutBuffer(f := FileSelect()) extension := "png" ; try "jpg" or "bmp" try DirDelete("yyy", 1) try DirDelete("zzz", 1) n := 100 DllCall("QueryPerformanceFrequency", "int64*", &frequency:=0) DllCall("QueryPerformanceCounter", "int64*", &start:=0) loop n ImagePut.BitmapToFile(buf.pBitmap, "yyy\1." extension) DllCall("QueryPerformanceCounter", "int64*", &end:=0) a := n / ((end - start) / frequency) DllCall("QueryPerformanceCounter", "int64*", &start:=0) loop n fn2(buf, "zzz\" A_Index "." extension) DllCall("QueryPerformanceCounter", "int64*", &end:=0) b := n / ((end - start) / frequency) last_file := "zzz\" n "." extension ;MsgBox FileExist(last_file) ? "Exists" : "Doesn't exist" ;MsgBox s MsgBox "BitmapToFile:`t`t" Round(a, 2) " fps" . "`nThread Pool:`t`t" Round(b, 2) " fps" . "`nNumber of Threads:`t`t" thread_count . "`nConvert Extension:`t`t" extension . "`nFrames per second (Higher is better)" , f fn(clone, &filepath, &pCodec, &ep, &hThread) { pBitmap := clone.pBitmap extension := "png" quality := "" ImagePut.select_filepath(&filepath, &extension) ImagePut.select_codec(pBitmap, extension, quality, &pCodec, &ep) pcb := callback(pBitmap, &filepath, pCodec, ep) ;DllCall(pcb) hThread := DllCall("CreateThread", "ptr", 0, "ptr", 0, "ptr", pcb, "ptr", 456, "uint", 0, "uint*", 0, "ptr") ; Export objects to manage lifetimes. return } fn2(buf, filepath2) { clone := buf.Clone() pCodec := &pCodec ep := &ep filepath := &filepath2 hThread := &hThread2 static queue := [] fn(clone, filepath, pCodec, ep, hThread) if queue.length >= thread_count { c := queue.RemoveAt(1) check := %c.hThread% start := A_TickCount DllCall("WaitForSingleObject", "ptr", check, "uint", 0xFFFFFFFF) global s .= "`n" A_TickCount - start ; lifetimes eliminated here. } if filepath2 ~= "^zzz\\" n { for c in queue DllCall("WaitForSingleObject", "ptr", %c.hThread%, "uint", 0xFFFFFFFF) } continuation := { clone: clone, pCodec: pCodec, ep: ep, filepath: filepath, hThread: hThread, __Delete: (self) => Tooltip(%self.filepath%) } queue.push(continuation) } Esc:: Reload ;DllCall(pcb) ;DllCall(GdipSaveImageToFile, "ptr", pBitmap, "wstr", filepath, "ptr", pCodec, "ptr", ep) callback( pBitmap, &filepath, pCodec, ep) { gdiplus := DllCall("GetModuleHandle", "str", "gdiplus.dll", "ptr") GdipSaveImageToFile := DllCall("GetProcAddress", "ptr", gdiplus, "astr", "GdipSaveImageToFile", "ptr") ncb := (A_PtrSize = 4) ? 28 : 81 pcb := DllCall("GlobalAlloc", "uint", 0, "uptr", ncb, "ptr") DllCall("VirtualProtect", "ptr", pcb, "ptr", ncb, "uint", 0x40, "uint*", 0) ; Retract the hex representation to binary. ;if (A_PtrSize = 8) { assembly := " ( Join`s Comments 48 89 4c 24 08 ; 0: mov [rsp+8], rcx 48 89 54 24 10 ; 5: mov [rsp+16], rdx 4c 89 44 24 18 ; 10: mov [rsp+24], r8 4c 89 4c 24 20 ; 15: mov [rsp+32], r9 48 83 ec 28 ; 20: sub rsp, 40 49 b9 00 00 00 00 00 00 00 00 ; 24: mov r9, .. (ep) 49 b8 00 00 00 00 00 00 00 00 ; 34: mov r8, .. (pCodec) 48 ba 00 00 00 00 00 00 00 00 ; 44: mov edx, .. (&filepath) 48 b9 00 00 00 00 00 00 00 00 ; 54: mov ecx, .. (pBitmap) 48 b8 00 00 00 00 00 00 00 00 ; 64: mov rax, .. (GdipSaveImageToFile) ff d0 ; 74: call rax 48 83 c4 28 ; 76: add rsp, 40 c3 ; 80: ret )" ; 81: DllCall("crypt32\CryptStringToBinary", "str", assembly, "uint", 0, "uint", 0x4, "ptr", pcb, "uint*", ncb, "ptr", 0, "ptr", 0) NumPut("ptr", GdipSaveImageToFile, pcb + 66) NumPut("ptr", pBitmap, pcb + 56) NumPut("ptr", StrPtr(filepath), pcb + 46) NumPut("ptr", pCodec.ptr, pcb + 36) NumPut("ptr", ep, pcb + 26) /* } else { assembly := " ( Join`s Comments 68 00 00 00 00 ; push .. (lParam) 68 00 00 00 00 ; push .. (wParam) 68 00 00 00 00 ; push .. (uMsg) 68 00 00 00 00 ; push .. (hwnd) b8 00 00 00 00 ; mov eax, .. (SendMessageW) ff d0 ; call eax c3 ; ret )" DllCall("crypt32\CryptStringToBinary", "str", assembly, "uint", 0, "uint", 0x4, "ptr", pcb, "uint*", ncb, "ptr", 0, "ptr", 0) NumPut("int", SendMessageW, pcb + 21) NumPut("int", hwnd, pcb + 16) NumPut("int", uMsg, pcb + 11) NumPut("int", wParam, pcb + 6) NumPut("int", lParam, pcb + 1) } */ ; return pcb return pcb }
- Attachments
-
- Screenshot 2024-07-04 152914.png (13.48 KiB) Viewed 2454 times
-
- Screenshot 2024-07-04 152255.png (11.91 KiB) Viewed 2454 times
-
- Posts: 3
- Joined: 12 Apr 2021, 18:21
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Not sure if you need any system details.. lmk or if you'd like more tests run?
Here's it run on 3 different images.
Here's it run on 3 different images.
- Attachments
-
- 2024_07_12_18_25_04.PNG (5.13 KiB) Viewed 2348 times
-
- 2024_07_12_18_24_30.PNG (5.1 KiB) Viewed 2348 times
-
- 2024_07_12_18_15_51.PNG (5.12 KiB) Viewed 2348 times
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
@TraitorJoes @sushibagel Thanks for the benchmarks!
New Benchmarks For Testing - Capture Screen and Save To File at 60 FPS
The following is an updated set of benchmarks that now uses the Desktop Duplication API to capture the screen. Because the Desktop duplication API only updates when there is a new image, your values should be capped at 60fps - which is what I'm aiming for across all computers whether they be fast or slow.
New Benchmarks For Testing - Capture Screen and Save To File at 60 FPS
The following is an updated set of benchmarks that now uses the Desktop Duplication API to capture the screen. Because the Desktop duplication API only updates when there is a new image, your values should be capped at 60fps - which is what I'm aiming for across all computers whether they be fast or slow.
- Attachments
-
- DirectX Screen Capture Benchmark.zip
- (60.37 KiB) Downloaded 49 times
-
- Posts: 7
- Joined: 21 Jun 2024, 12:43
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
@iseahound
Here are my test runs.
[Mod edit: Removed img tags from around attachments which resulted in broken image icons. They are only for use with URLs to image files.]
Here are my test runs.
[Mod edit: Removed img tags from around attachments which resulted in broken image icons. They are only for use with URLs to image files.]
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Thanks for sharing, can use this library to convert an image to black-and-white?
- Komrad Toast
- Posts: 51
- Joined: 28 Jun 2024, 02:19
- Contact:
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
@iseahound
Awesome work! Just for fun I used the example on the github of looping through pixels with my new Color library, and it works perfectly! My library is a bit slow in this regard, but it wasn't really meant for Image Manipulation anyways. A 256x256 image takes ~6 seconds to invert .
Again, Awesome work!
Awesome work! Just for fun I used the example on the github of looping through pixels with my new Color library, and it works perfectly! My library is a bit slow in this regard, but it wasn't really meant for Image Manipulation anyways. A 256x256 image takes ~6 seconds to invert .
Code: Select all
#Include <Classes/Color>
#Include ImagePut.ahk
pic := ImagePutBuffer([0, 0, 256, 256])
pic.Show()
for x, y, curColor in pic
pic[x, y] := Color(curColor).Invert().ToHex("0xFF{R}{G}{B}").Full
pic.Show()
Again, Awesome work!
Last edited by Komrad Toast on 16 Aug 2024, 07:02, edited 1 time in total.
- Komrad Toast
- Posts: 51
- Joined: 28 Jun 2024, 02:19
- Contact:
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Actually, this is surprising...
I used my current implementation of the Inversion algorithm, then a GDI+ ColorMatrix, then GdipBlendColor. These are the results from one test, but I ran it many times and the current implementation was consistently faster.
Edit: Oof, just using this gets a 256x256 pixel image inverted in 0.27 seconds.
I used my current implementation of the Inversion algorithm, then a GDI+ ColorMatrix, then GdipBlendColor. These are the results from one test, but I ran it many times and the current implementation was consistently faster.
Edit: Oof, just using this gets a 256x256 pixel image inverted in 0.27 seconds.
Code: Select all
#Include ImagePut.ahk
pic := ImagePutBuffer([0, 0, 256, 256])
pic.Show()
for x, y, curColor in pic
pic[x, y] := curColor ^ 0xFFFFFFFF
pic.Show()
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Since you're on the topic of optimizing, do you think https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-colorhlstorgb would be faster?
The for color; for x, y; and for x, y, color syntax is convenient yet slow.
The for color; for x, y; and for x, y, color syntax is convenient yet slow.
- Komrad Toast
- Posts: 51
- Joined: 28 Jun 2024, 02:19
- Contact:
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
I've been looking in to shlwapi. I tried using the ColorRGBToHSL func, but it was spitting out incorrect results. Probably just me not giving it input in the right format. But I have almost no doubt it would be faster. The GDI calls that I made were honestly only that slow because of the way that my color class stores the color data (I made it to work with single colors, mainly for web development, etc).
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
I am creating an emoji display that smoothly follows the mouse along with a tooltip.
The tooltip was successful, but the imageshow is behaving less than ideally.
Are there any best practices?
I tried my best to implement it, but the movement is awkward.
The tooltip was successful, but the imageshow is behaving less than ideally.
Are there any best practices?
I tried my best to implement it, but the movement is awkward.
Code: Select all
global hWnd := 0
UpdateImagePosition() {
MouseGetPos(&X, &Y)
X -= 10
Y += 16
if (hWnd) {
WinMove(X, Y, , , "ahk_id " hWnd)
} else {
hWnd := ImageShow(LoadPicture("C:\Windows\System32\shell32.dll", "Icon44"), , [X, Y, 40, 40])
}
}
SetTimer(UpdateImagePosition, 5)
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Stop calling LoadPicture inside your function... Either call it outside and reference the global variable inside your function or assign it to a static variable inside the function.
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
@dostroll Yeah this disgusting code:
Faster?
Slower?
I've pushed an update to ImagePut to support this hack, you'll need to download a new copy: https://github.com/iseahound/ImagePut/blob/master/ImagePut.ahk (can't be posted on the forum due to size)
Faster?
Code: Select all
#include ImagePut.ahk
hWnd := ImageShow(LoadPicture("C:\Windows\System32\shell32.dll", "Icon44"), , [0, 0, 40, 40])
; Creates a user defined callback using multimedia timers with a resolution of 1ms.
; The callback is placed in the wParam and called when the window message receives 0x8003.
DllCall("winmm\timeSetEvent"
, "uint", 1 ; uDelay
, "uint", 1 ; uResolution
, "ptr", ImagePut.SyncWindowProc(hwnd, 0x8003, ObjPtr(UpdateImagePosition)) ; lpTimeProc
, "uptr", 0 ; dwUser
, "uint", 1 ; fuEvent
, "uint")
UpdateImagePosition(hwnd) {
DllCall("GetCursorPos", "ptr", point := Buffer(8))
, x := NumGet(point, 0, "int") - 10
, y := NumGet(point, 4, "int") + 16
; Don't know why UpdateLayeredWindow is faster compared to WinMove.
DllCall("UpdateLayeredWindow"
, "ptr", hwnd ; hWnd
, "ptr", 0 ; hdcDst
,"uint64*", x << 32 >>> 32 | y << 32 ; *pptDst
, "ptr", 0 ; *psize
, "ptr", 0 ; hdcSrc
, "ptr", 0 ; *pptSrc
, "uint", 0 ; crKey
, "uint*", 0xFF << 16 | 0x01 << 24 ; *pblend
, "uint", 2) ; dwFlags
}
Code: Select all
#include ImagePut.ahk
hWnd := ImageShow(LoadPicture("C:\Windows\System32\shell32.dll", "Icon44"), , [0, 0, 40, 40])
; Using this causes some "jumping" when moving the image.
SetTimer(UpdateImagePosition.bind(hwnd), 1) ; Updates every tick (10 or 15.6 ms)
UpdateImagePosition(hwnd) {
DllCall("GetCursorPos", "ptr", point := Buffer(8))
, x := NumGet(point, 0, "int") - 10
, y := NumGet(point, 4, "int") + 16
; Don't know why UpdateLayeredWindow is faster compared to WinMove.
DllCall("UpdateLayeredWindow"
, "ptr", hwnd ; hWnd
, "ptr", 0 ; hdcDst
,"uint64*", x << 32 >>> 32 | y << 32 ; *pptDst
, "ptr", 0 ; *psize
, "ptr", 0 ; hdcSrc
, "ptr", 0 ; *pptSrc
, "uint", 0 ; crKey
, "uint*", 0xFF << 16 | 0x01 << 24 ; *pblend
, "uint", 2) ; dwFlags
}
Re: ImagePut - A core library for images in AutoHotkey (Now supports HEIC & WEBP)
Code: Select all
#include ImagePut.ahk
AnimatedCursor("https://media.tenor.com/6ceOmdT7SHkAAAAi/emoji-emojis.gif", -15, 32,, 100)
AnimatedCursor("https://media.tenor.com/rbIQJHPHD6UAAAAi/cat-shoot.gif", 32, -50)
; AnimatedCursor("https://media.tenor.com/dmYlPVcctp8AAAAi/discord-emoji.gif")
AnimatedCursor(image, dx := 0, dy := 0, width?, height?) {
; Omit width or height to keep aspect ratio
hwnd := ImageShow(image,, [0, 0, width?, height?],, 0x80088 | 0x20) ; Clickthrough
; Creates a user defined callback using multimedia timers with a resolution of 1ms.
; The callback is placed in the wParam and called when the window message receives 0x8003.
callback := ObjPtrAddRef(UpdateImagePosition.bind(dx, dy))
pTimeProc := ImagePut.SyncWindowProc(hwnd, 0x8003, callback)
timer := DllCall("winmm\timeSetEvent"
, "uint", 1 ; uDelay
, "uint", 1 ; uResolution
, "ptr", pTimeProc ; lpTimeProc
, "uptr", 0 ; dwUser
, "uint", 1 ; fuEvent
, "uint")
free() => (
DllCall("winmm\timeKillEvent", "uint", timer),
DllCall("GlobalFree", "ptr", pTimeProc),
ObjRelease(callback),
DllCall("DestroyWindow", "ptr", hwnd)
)
return free
UpdateImagePosition(dx, dy, hwnd) {
DllCall("GetCursorPos", "ptr", point := Buffer(8))
, x := NumGet(point, 0, "int") + dx
, y := NumGet(point, 4, "int") + dy
; Don't know why UpdateLayeredWindow is faster compared to WinMove.
DllCall("UpdateLayeredWindow"
, "ptr", hwnd ; hWnd
, "ptr", 0 ; hdcDst
,"uint64*", x << 32 >>> 32 | y << 32 ; *pptDst
, "ptr", 0 ; *psize
, "ptr", 0 ; hdcSrc
, "ptr", 0 ; *pptSrc
, "uint", 0 ; crKey
, "uint*", 0xFF << 16 | 0x01 << 24 ; *pblend
, "uint", 2) ; dwFlags
}
}
Return to “Scripts and Functions (v2)”
Who is online
Users browsing this forum: gdqb521 and 40 guests