iseahound / imageput Goto Github PK
View Code? Open in Web Editor NEWA core library for images in AutoHotkey. Supports AutoHotkey v1 and v2.
Home Page: https://www.autohotkey.com/boards/viewtopic.php?f=83&t=76633
License: MIT License
A core library for images in AutoHotkey. Supports AutoHotkey v1 and v2.
Home Page: https://www.autohotkey.com/boards/viewtopic.php?f=83&t=76633
License: MIT License
HBitmapToPngFile(hBitmap, destPngFilePath) {
; from https://www.autohotkey.com/boards/viewtopic.php?p=418815#p418815
static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
, IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
, GUID_ContainerFormatPng := "{1B7CFAF4-713F-473C-BBCD-6137425FAEAF}"
, WICBitmapUseAlpha := 0x00000000, GENERIC_WRITE := 0x40000000
, WICBitmapEncoderNoCache := 0x00000002
GUID := Buffer(16, 0)
DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatPng, "Ptr", GUID)
IWICImagingFactory := ComObject(CLSID_WICImagingFactory, IID_IWICImagingFactory)
ComCall(CreateBitmapFromHBITMAP := 21, IWICImagingFactory, "Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapUseAlpha, "PtrP", &IWICBitmap := 0)
ComCall(CreateStream := 14, IWICImagingFactory, "PtrP", &IWICStream := 0)
ComCall(InitializeFromFilename := 15, IWICStream, "WStr", destPngFilePath, "UInt", GENERIC_WRITE)
ComCall(CreateEncoder := 8, IWICImagingFactory, "Ptr", GUID, "Ptr", 0, "PtrP", &IWICBitmapEncoder := 0)
ComCall(Initialize := 3, IWICBitmapEncoder, "Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
ComCall(CreateNewFrame := 10, IWICBitmapEncoder, "PtrP", &IWICBitmapFrameEncode := 0, "Ptr", 0)
ComCall(Initialize := 3, IWICBitmapFrameEncode, "Ptr", 0)
ComCall(WriteSource := 11, IWICBitmapFrameEncode, "Ptr", IWICBitmap, "Ptr", 0)
ComCall(Commit := 12, IWICBitmapFrameEncode)
ComCall(Commit := 11, IWICBitmapEncoder)
for v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IWICStream, IWICBitmap]
ObjRelease(v)
}
For example, I want to scale an image with a resolution of 3000x2000 to 100x100
maybe can support it like this ?
{scale : 100*100}
Hello!
First of all, terrific job! While I don't use your lib, quite often recommend it to other users (usually the less experienced). It is one of the few one-fits-all that actually works; plus it is very easy to get it working. Thanks for the superb effort.
So... a user raised an issue in the AHK_H2 repo about a recursion problem, the lib has a "sentinel value", that conflicts with an H-only feature:
; H adds this:
; Object.Prototype.Get()
; This creates a recursion problem:
keywords := {base: {__get: this.get}}
There are two ways of addressing the issue, renaming the method (say this.got
):
keywords := {base: {__get: this.got}}
Or explicitly pass the object reference rather than rely on this
:
keywords := {base: {__get: (self, name, *) => this.get(self, name)}}
That in turn will require the method to change:
; From:
static get(name, p*) {
return ObjHasOwnProp(this, name) ? this.name : ""
}
; To:
static got(name, p*) {
return ObjHasOwnProp(self, name) ? self.%name% : ""
}
In any case, the method has a bug. It will always try to grab the .name
property instead of evaluating the name
variable into a dynamic property.
Let me know if you are interested in adding support for the H release to create a PR.
When I updated to v1.5, the pdf function did not work.
If I use version of v1.3 (sorry I can't tell which version of v1.3 it is), the pdf function works fine.
I packaged a pdf file with the test code and the v1.3 library files for testing.
The main reference for ImagePutWindow documents the arguments (title, pos, style, etc.) individually but doesn't discuss calling the function with keyword instead of positional arguments. Then in the documentation for the flags, we get examples with keyword arguments for the image and the flags, but no examples/discussion of how to include other arguments (pos, title, etc.) when calling with flags.
I couldn't figure it out — my AHK is occasional — so I took the long way round: scaled with ImagePutBuffer first, then called ImagePutWindow with positional arguments, starting with the buffer pointer.
Additional examples using all the arguments, in both positional and keyword versions, would be appreciated, for those of us beginners, with perhaps a little explanation. Thanks.
ImageSearch has two components:
Prioritize:
Here is some code to help you:
#include *i ImagePut%A_TrayMenu%.ahk
#include *i ImagePut (for v%true%).ahk
#singleinstance force
pic := ImagePutBuffer("[images]\h.png") ; Screen capture
pic.show() ; or ImageShow(pic) ; Show image
if xy := pic.ImageSearch("[images]\g.png") { ; Search image
MouseMove xy[1], xy[2] ; Move cursor
Send "{MButton}" ; MsgBox pic[xy*]
} else Tooltip "no"
https://github.com/iseahound/ImagePut/assets/9779668/3c2587da-d6ed-449d-af78-89633e2a7442
https://github.com/iseahound/ImagePut/assets/9779668/25a63f1b-8fb2-4c2a-84c4-34867b1e5ece
Useful ideas:
boyer moore (and string search algorithms in general)
multi-dimensional string searcch
Has ImageSearch been a priority in the public domain?
Some research papers would be immensely valuable.
Current performance is about 19 fps, compared to pixelsearch's 4000 fps. Aim for 800 fps or higher.
Dears,
Appreciate the library, thanks so much!
What, if any, non-UTF8 characters could ImagePutBase64 be generating in the Base64 string? Not sure if this is actually the case but..
I'm using the call below (from ImagePut for v1) and sending the output to a websocket server which works great, albeit the server randomly (and rarely) throws "invalid UTF-8 payload" which I'm struggling to catch/sanitize on the client before sending.
ImagePutBase64({image: [0, 0, A_ScreenWidth, A_ScreenHeight ], scale: ["", 600]}, "jpg", 75)
When able, kindly share whatever you deem helpful. Thank you for your time and effort!
Is there any workaround to get the bitmap of a hidden window? When I hide the window I get a full blank bitmap...
This is the second attempt at improving ImageSearch.
The following fixes a bug where the last row of images is not searched.
Current implementation of SSE2 causes pixels to be double or triple counted.
Only occurs when the number of side by side colors is more than 3:
#include *i ImagePut%A_TrayMenu%.ahk
#include *i ImagePut (for v%true%).ahk
#singleinstance force
pic := ImagePutBuffer("d.png") ; Load image
pic.show() ; or ImageShow(pic) ; Show image
if xys := pic.PixelSearchAll([0xED1C24, 1, 2, 0x000000]) { ; Get [x, y] of 0xFFFFFF
MouseMove(xys[1]*) ; Move cursor
Send "{MButton}"
MsgBox xys.length
}
else Reload ; Restart
for the image:
https://github.com/iseahound/ImagePut/assets/9779668/9d3c78a9-5ba5-4e3a-b178-c0616966a0fe
The solutions are here:
pixelsearchall3: https://godbolt.org/z/evaxq93fd
pixelsearch3: https://godbolt.org/z/drTev8Kx3
In addition: optimizations have also been made such that the SIMD instructions exist one after the other, which produced a 20% increase in speed in my testing.
Hi! First of all, thank you for this amazing library, I'm having a problem when running multiple timers with ImagePutBuffer(windowName)
. It all works fine, but suddenly, I get this message pStream cannot be zero
after running the script for some time. In this script, I usually get images from 4 different windows and when one stop working every other stop working as well.
I want to perform zooming, rotating, mirroring on the already opened image.
can it be achieved?
Hi! I've seen this problem in the classic gdip library where the window flicker/blink/flash when taking the bitmap of the active window. This is happening for a specific program in my case. Is there a way to solve this? Thanks.
I know there are many ways to do this, but when people use ImagePut, they probably prefer to use the built-in methods of ImagePut.
GdipSaveImageToFile seems not support the filetype...
is there any other method to do this?
thanks very much!!!
Convert manga into pdf files!
Also, add options for auto sharpen and auto brightness / contrast.
#Requires AutoHotkey v2.0.11+
#Include <ImagePut>
blue_shape_black_background_base64 := "iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AcxV9TpSIVQQuKKGSonSyIijhKFYtgobQVWnUwufRDaNKQpLg4Cq4FBz8Wqw4uzro6uAqC4AeIs4OToouU+L+k0CLGg+N+vLv3uHsHCPUyU82OcUDVLCMVj4nZ3IoYeIUfIxhAHyISM/VEeiEDz/F1Dx9f76I8y/vcn6NHyZsM8InEs0w3LOJ14ulNS+e8TxxiJUkhPiceM+iCxI9cl11+41x0WOCZISOTmiMOEYvFNpbbmJUMlXiKOKyoGuULWZcVzluc1XKVNe/JXxjMa8tprtMcRhyLSCAJETKq2EAZFqK0aqSYSNF+zMM/5PiT5JLJtQFGjnlUoEJy/OB/8LtbszA54SYFY0Dni21/jAKBXaBRs+3vY9tunAD+Z+BKa/krdWDmk/RaSwsfAb3bwMV1S5P3gMsdYPBJlwzJkfw0hUIBeD+jb8oB/bdA96rbW3Mfpw9AhrpaugEODoFIkbLXPN7d1d7bv2ea/f0AqcVyvYg/9TYAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfoAx4AMwLbwG0vAAAATklEQVQ4y2NkYGD4z0AFwMRAJUA1g1gwRMSJ9OlLRjwuEichuNDUshBrIyHLmEgyBI/c4Iu1EWcQvvSEQ46FVA3EuQhf+iGQnhiHbzECAMmxDz2uUlYUAAAAAElFTkSuQmCC"
ib := ImagePutBuffer(blue_shape_black_background_base64)
search := ImagePutBuffer(blue_shape_black_background_base64)
search.TransColor(0) ; black
xy := ib.ImageSearch(search)
The variable xy
is Array [0,0]
.
The variable xy
is 0
.
I found that filepath in ImagePutFile() can't use absolute path because colons(':') will be removed.
So I end up deleting the colon in RegExReplace.
When crop placed in high frequency loop, ram memory overflow happened due to not solving Destroy pBitmap, I tried to fix it and it worked
original code:
Crop(x, y, w, h) {
DllCall("gdiplus\GdipGetImagePixelFormat", "ptr", this.pBitmap, "int*", &format:=0)
DllCall("gdiplus\GdipCloneBitmapAreaI", "int", x, "int", y, "int", w, "int", h, "int", format, "ptr", this.pBitmap, "ptr*", &pBitmap:=0)
return ImagePut.to_buffer(pBitmap)
}
I am using the ahk v1 version, and use the imageputwindow function as follows
imagewindow_handle := ImagePutWindow(imagefile,"image window",coordinates,0x80000000,0x08000028)
When I use a webp file it gives me an error.
Gif files work fine.
Example animated webp file
https://www.tutorialexample.com/wp-content/uploads/2020/09/gif-test-2.webp
Example animated giffile
https://www.tutorialexample.com/wp-content/uploads/2020/09/gif-test.gif
The supported formats website says animated webp should work.
https://github.com/iseahound/ImagePut/wiki/Quick-Start#accepts
At the Release v1.9 ImagePut.ahk(for v2)
file, there has no PixelSearchAll()
and ImageSearchAll()
.
I can find it at the master branch.
Why not update the release version?
Hello!
First of all, thank you for this project, it's amazing!
I have a script that uses ImagePut
to update information about a window every 200ms. The update function is something like this:
updateInfo() { img := ImagePutBuffer("window") this.getInfoX(img) this.getInfoY(img) this.getInfoZ(img) }
The getInfo
functions mainly check pixel colors at different locations.
After about 1 hour of running the script I always get this error:
Parameter #1 of File.Prototype.RawRead is invalid.
Specifically: 0
Line#
1360: file := FileOpen(image, "r")
1361: hData := DllCall("GlobalAlloc", "uint", 0x2, "uptr", file.length, "ptr")
1362: pData := DllCall("GlobalLock", "ptr", hData, "ptr")
---> 1363: file.RawRead(pData, file.length)
1364: DllCall("GlobalUnlock", "ptr", hData)
1365: file.Close()
If the bitmap is bottom-up, ImageEqual() will fail.
what I know is:
use pBitmap
: has source from rect of screent, file, clipboard and so on,
use hBitmap
: no clear source, create by CreateDIBSection
pBitmap
and hBitmap
can covert to each other.
I see BitmapBuffer
in your code, why use this?
put_window
use CreateWindowEx
instead of gui
.
too much doubt...
BTW, I write a funtion for crop
to get new postion by width, fyi ^_^
;v<0 width - abs(v)
;v<1 width * v
;v<width v
;v≥width other
forCrop(width, v, other:=0) {
if (v == 0)
return v
if (v < 0) {
v := width - abs(v)
if (v < 0)
v := other
} else if (v < 1) {
v := round(width * v)
} else if (v > width) {
v := other
}
return v
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.