Skip to content

Internal Documentation

Edison Hua edited this page Apr 3, 2025 · 16 revisions

Basics

If one wishes to convert from a url to a file, then the domain is url and the codomain is file respectively.

coimage := "https://picsum.photos/1000"
stream := ImagePut.URLToStream(coimage)
filepath := ImagePut.StreamToFile(stream)

A more general question: What if any input image is to be converted into a file?

coimage := "https://picsum.photos/1000"
domain := ImageType(coimage)
stream := ImagePut.ImageToStream(domain, coimage)
filepath := ImagePut.StreamToFile(stream)

Finally, for any input or output: (using a bitmap intermediate because it handles more domains)

codomain := "file"
coimage := "https://picsum.photos/1000"
domain := ImageType(coimage)
ImagePut.gdiplusStartup()
pBitmap := ImagePut.ImageToBitmap(domain, coimage)
image := ImagePut.BitmapToImage(codomain, pBitmap)

Naturally this is all done by image := ImagePut("file", "https://picsum.photos/1000")

Don't worry about the terminology for now. It comes from linear algebra. As a brief guide, a coimage is kind like the image, except the coimage can be png or webp but the image is the same set of pixels for both formats. The domain can be thought of as the source context and the codomain as the destination context.

Error Values

  1. """"
    • The empty string is always returned as-is.
    • Meaning: The conditions are not present, so the user should use an if-else block to provide an alternative.
  2. unset0 → error
    • A value that was not processed in a function is unset and returned as zero.
    • Meaning: The input was not processed and the calling function should use an if-else block to provide an alternative.
    • If a 0 is received, try another function or throw an error.
    • Meaning: The calling function has tried different functions. Because it could not process the input it must throw an error.
    • An error is thrown so the calling function must use a try-catch block.
    • Meaning: The function failed to process the input. In other words, it is insufficient.

Imagine trying to catch fish with different nets. Some nets have wide or narrow rims. Some nets have tight or loose openings. Every net is kind of different as they're meant to catch different fish! If trying one net gets 3 fish, that's great! But sometimes the fish are too young, and they swim out of the loose openings. Here the fish remain uncaught (or unset), so the number of fish caught is 0. Maybe another net will work. But what if, after trying all the nets, there are still no fish? Well, it stands to reason that it's a poor fishing spot. So one throws a fit (or an error), and gets up, and drives down the lake, or comes back at a different time of day. In other words, despite all the nets available, they were insufficient.

Returning empty handed (or the empty string) with no fish happens sometimes! It just means the weather wasn't right, or the water was too warm, or one of a million reasons that actual fishermen come up with. The conditions just weren't there.

---------------- WIP OUTDATED INFORMATION BELOW -----------------------

The domain refers to the space of the source. The codomain is the space of the destination. The part of the domain that is mapped into the codomain is called in image. The coimage refers to the

linear mapping

y

Now if you dont know

x

Calling ImagePut("file", "cats.jpg") is the same as calling ImagePutFile("cats.jpg").

There are 3 steps:

  1. Calling ImageType on the input image.
  2. Passing the type and input image to ToBitmap.
  3. Passing the Bitmap and any optional arguments to BitmapToCoimage.

Example:

#include ImagePut.ahk
ImagePut.gdiplusStartup()                                   ; Allow handling of GDI+ bitmaps.
image_type := ImagePut.ImageType("cats.jpg")                ; Get the image_type as "file".
pBitmap := ImagePut.ToBitmap(image_type, "cats.jpg")        ; Convert to pixel data.
hwnd := ImagePut.BitmapToCoimage("window", pBitmap, "Cat!") ; Show the image on-screen with a caption.

DontVerifyImageType

Dereferences objects like {file: "cats.jpg"} to "cats.jpg".

ImageType

Where all the magic happens. Calling ImagePut.ImageType("cats.jpg") will retrieve the windows image data type.

ToBitmap(type, image)

This function converts an image into a bitmap. Dispatches to all functions beginning with from_XXX.

pBitmap := ImagePut.ToBitmap("file", "cats.jpg")

BitmapToCoimage(cotype, pBitmap, p1, p2)

Converts a bitmap into any supported image type. Dispatches to all functions beginning with put_XXX.

ImagePut.BitmapToCoimage("window", pBitmap)

ToStream(type, image)

This function converts an image into a stream. Dispatches to all functions beginning with get_XXX.

pStream := ImagePut.ToStream("file", "cats.jpg")

StreamToCoimage(cotype, pStream, p1, p2)

Converts a stream into any supported image type. Dispatches to all functions beginning with set_XXX.

filepath := ImagePut.StreamToCoimage("file", pStream)

from_XXX

These functions always convert to a pBitmap.

; Get the current wallpaper as a bitmap.
pBitmap := ImagePut.from_wallpaper()

; Get the current cursor as a bitmap.
pBitmap := ImagePut.from_cursor()

; Get a web image as a bitmap.
pBitmap := ImagePut.from_url("https://i.imgur.com/PBy1WBT.png")

put_XXX

These functions always convert from a bitmap into some type.

; Set the current wallpaper.
ImagePut.put_wallpaper(pBitmap)

; Set the cursor.
ImagePut.put_cursor(pBitmap)

get_XXX

These functions always convert to a pStream.

set_XXX

These functions always convert from a stream into some type.

Streams vs. MemoryStreams

SHCreateMemStream creates a memorystream. CreateStreamOnHGlobal creates a stream. The difference between the two outputs is that only GetHGlobalFromStream is supported by streams. Therefore to maximize compatibility, all set_XXX functions will create streams without the shlwapi functions. And all get_XXX functions will read both streams and memorystreams by never calling GetHGlobalFromStream.