Imagine a scenario where you have a file but you're trying to get it uploaded into an API. Or you have a function that returns some strange image format, is there any way you can *just* get it to show its contents? If you pass anything, literally anything you believe is an image to ImagePutWindow() it will show up on screen. And then you can magically transform it to be compatible with that specific API.
Working with images should be this easy. ImagePut has automatic type inference, meaning that it will guess whether the input is (1) a file (2) a website url or (3) a series of coordinates that map to the screen. This functionality enables the user to only memorize a single function for any possible input. For a full list of supported input types, click on the documentation link here. For output types click here.
; Saves a JPEG as a base64 encoded GIF.
str := ImagePutBase64("cats.jpg", "gif")
There's also some weird functions like ImagePutCursor which lets you set anything as your cursor. Make sure you don't choose an extremely large image!
Finally, there are several advanced features. The first is the ability to specify the input type directly. The second is cropping and scaling functionality. Third is use of ImageEqual() a function that can compare multiple inputs across different windows image data types!
; Declare input type as file.
ImagePutWindow({file: "cats.jpg"})
; Scale 2x and crop 10% from each edge.
ImagePutWindow({file: "cats.jpg", scale: 2, crop:["-10%", "-10%", "-10%", "-10%"]})
; Unknown image type declared as "image" to be cropped to 200x200 pixels.
ImagePutWindow({image: "cats.jpg", crop: [0, 0, 200, 200]})
; Compare a url to a file.
MsgBox % ImageEqual("https://example.com/cats.jpg", "cats.jpg")
; Validate an image as an actual image.
ImageEqual("cats.jpg")
Design Philosophy
100% Compatibility with Gdip_All.ahk
ImagePut is designed to be the fastest
ImagePut should serve as a reference implementation
Specific conversions between formats like PNG file to hIcon are not considered
Users should be able to replace uses of ImagePut with individual functions
Therefore users should be copy and paste individual functions
If you need help extracting a function please ask!
Help and Support
Feel free to ask for any help, questions, or post suggestions, etc.
Re: ImagePut - Puts an image from anywhere to anywhere
Posted: 22 May 2020, 17:13
by robodesign
Impressive work, I'd say, just by reading the well written code.
Re: ImagePut - Puts an image from anywhere to anywhere
Posted: 22 May 2020, 19:51
by iseahound
Quick note for anyone who already downloaded this class: I've added an error message to ImagePutBitmap(image) letting users know that their pointer is out of scope. ImagePut loads and unloads GDI+ (transparently) with each call unless the user loads it manually.
Re: ImagePut - Puts an image from anywhere to anywhere (convert, crop, scale)
From now on, major developments will happen on the v2 branch and be backported to v1. Writing code is just so much smoother on v2, and several built in functions are just better. As a short summary, Clipboard and Monitor functions have been added to v2 and backported to v1. The clipboard functions are less robust in v1 but still support transferring a PNG stream instead of an hBitmap like tic's Gdip code did. The monitor types only exist on v2 with the exception of sending the number 0 to mean the entire virtual screen.
Re: ImagePut - Windows Image Transformation Library
Posted: 07 Sep 2020, 21:21
by iseahound
Fixed monitor numbers as an input type, so that ImagePutFile(1) now properly copies the first monitor, ImagePutFile(2) the second, and so on...
Re: ImagePut - Windows Image Transformation Library
Thanks, but I noticed that the cursor changes sometimes for ex. when i read pdfs files and there is no way to force it to stay on the arrow.
A simple way I have to solve this problem is to make a GUI appear as a transparent layer. I also ensured that the invisible gui does not occupy the whole screen. (so that I keep access to the menu and scroll bars) and this GUI is also temporarily disabled to allow zooming with the mouse wheel.
Here is the new script with these features. It's a bit messy but it works pretty well.
Re: ImagePut - Library for moving image data on Windows
Posted: 11 Aug 2021, 10:22
by tuzi
Thank you, @iseahound.
This is the best library I've ever used for image loading, display, and conversion.
So useful, makes everything easy, I love it!
Re: ImagePut - Library for moving image data on Windows
Posted: 15 Aug 2021, 00:28
by william_ahk
For ImagePutWindow, it would be really helpful for the window to be responsive to the screen size.
Re: ImagePut - Image library for converting to files, streams, windows, base64, urls, cursors, screen coordinates, clipb
I don't normally post release notes in the v1 forum, since we should all be slowly migrating to v2. However, this version contains so many bugfixes and optimizations, that upgrading is a must. I have verified that every conversion works, and have taken steps to ensure that there are no bugs. This release offers stability and speed. As my understanding of Windows API increases, so does my coding ability.
Notably, it is being used by PaddleOCR which is why there are so many optimizations. See here: viewtopic.php?f=6&t=94856
ImagePut was originally developed from some code I was using to convert images to files and base64. That was an old project that also did OCR, called Vis2. So it's kind of going back to its roots as a front-end for OCR. Very cool
@william_ahk Sorry not this release, ImagePutWindow needs a lot of work, I promise it'll happen next release. It looks great and seems like it works well, but ImagePutWindow is a function I wrote out of frustration and just published it in some haphazard form. Release Notes
Support for streams as a intermediate has been added to base64, file, hex, RandomAccessStream, stream, and url. Previously, ImagePutFile(url) would convert via: url → decode → pixels → encode → file. Now it can directly convert: url → stream → file.
Increase speed by skipping encoding and decoding of compressed images when using streams.
File hashes are now preserved when moving between stream compatible data types.
File extensions are also preserved from the input where possible.
For previous behavior, the flag ForceDecodeImagePixels has been added.
An additional flag, ForcePushImageToMemory controls whether pBitmaps should load their pixel data immediately.
ImageEqual has been completely revamped.
Will now throw errors if supplied with an improper image.
Calling with one image parameter will now verify that image is valid. Previously, ImageEqual(image) always returned true.
Bitmaps are now cloned to solve the problem where multiple calls to LockBits would fail, if the bitmaps shared the same stream. Calling LockBits from the clone will lock the original bitmap so the underlying stream is never locked.
CloneImage has been replaced with GdipCloneBitmapAreaI to preserve the native PixelFormat when cloning.
Support for bitmaps with negative stride is implicit when cloning.
Bugfixes
Declared types {type:image} were broken by v1.1.
A 24-bit image passed to put_clipboard would cause the script to crash.
Some applications expected a bottom-up bitmap from the clipboard.
Not supplying a valid window handle to OpenClipboard would cause EmptyClipboard to crash.
Calling ObjRelease() on a clipboard stream would delete the clipboard data.
select_codec() now throws instead of defaulting to PNG.
Internal Documentation
from_XX and put_XX has been factored into get_XX and set_XX if the function used a stream.
There are two types of streams: pStream from CreateStreamOnHGlobal and pMemoryStream from SHCreateMemStream.
Calls to SHCreateMemStream (pMemoryStream) have been removed as GetHGlobalFromStream is only supported on pStreams.
All get_XX functions create pStreams. All set_XX functions read both pStream and pMemoryStream.
Multiple bitmaps created on a single stream are now resolved by calling either GdipImageForceValidation through the ForcePushImageToMemory flag, or by calling GdipCloneImage on a given pBitmap.
put_screenshot now uses bilinear scaling.
put_screenshot defaults to the top left corner of the screen.
Return values of uint have been replaced with HRESULT in v2.
Re: ImagePut - Image library for converting to files, streams, windows, base64, urls, cursors, screen coordinates, clipb
Posted: 07 Oct 2021, 19:26
by william_ahk
Great, thank you so much!
Re: ImagePut - Image library for converting to files, streams, windows, base64, urls, cursors, screen coordinates, clipb
Posted: 07 Oct 2021, 21:18
by iseahound
@william_ahk Out of curiosity, would something like a double click to close window be nice? left/right click?
Re: ImagePut - Image library for converting to files, streams, windows, base64, urls, cursors, screen coordinates, clipb
Posted: 07 Oct 2021, 22:04
by william_ahk
@iseahound Yes this can be very useful for borderless windows, double left click to close the window is a very common implementation.
Re: ImagePut - Image library for converting to files, streams, windows, base64, urls, cursors, screen coordinates, clipb
Posted: 10 Oct 2021, 19:29
by iseahound
Updated first post. Added a simple right click to close the window. ImagePutWindow now responds to the screen size. However, I did not have the time to completely revamp ImagePutWindow, so it (just works)™.
Note to self
Edit: A quick note for myself before I forget again, the reason why ImageEqual is separate from ImagePut and does not exist as a .equals() method is because equality is a higher inductive type. What does that mean? It means that there are potentially equalities of equalities, and equalities of those equalities... ImageEqual only compares the pixel data, but it could compare the file hashes for example. And so if we consider the set of all images that are equal to each other in the form of pixel data, we can imagine a set of images that have been scaled up or down by some factor, or perhaps flipped or mirrored, so we consider that to be an equality over what ImageEqual currently does, and going further we can consider images that are not pixel perfect even in the sense of scaling or rotation, that are perhaps casualties of compression, and consider them to be equal... The tower of equalities has no real limit, and that's basically why ImageEqual is its own class and function.
Re: ImagePut - Image library for converting to files, streams, windows, base64, urls, cursors, screen coordinates, clipb