Read a pixel. Returns a color (.r/.g/.b/.a, 0-1), or nil when out of bounds. Raises if the image isn't loaded yet — await it with image:ready() or datumhue.ready{...} first.
Replay one or more pictures onto this image in a single atomic pass, every recorded op in order. Accepts a single picture or an array of them (drawn in order, sharing draw state). The image is never seen partially updated. Raises if this image, or any image a picture blits from, isn't loaded yet — await it with image:ready() or datumhue.ready{...} first; nothing is drawn when it raises.
Cursor position in this image's own pixel coordinates (Y-down from the top-left), accounting for how the image is displayed — correct even when it is letterboxed or scaled inside a larger element, at every zoom and stretch mode. Nil when the cursor isn't over a mounted, unoccluded instance. The fit-aware companion to elem:mouse_position(); mount the image first.
The position of the touch with this id in this image's own pixel coordinates (y down from the top-left), taking into account how the image is displayed. Nil when the touch isn't down, belongs to a touch control, or isn't over a mounted, unoccluded instance. The touch companion of cursor(); two touches on two images each resolve.
Example
datumhue.on_update(function(dt)
for _, touch inipairs(datumhue.input.touches()) do-- In the image's own pixels, through how it is displayed; nil-- off it.local at = image:touch(touch.id)
if at thenprint(touch.id, at)
endendend)
Remove the image and any UI element mounting it, freeing its texture. Afterwards state reads failed, calling remove again does nothing, and every other method and property of the handle raises. Copies already made from it (a sprite, a material texture, a shader channel) keep rendering.
Mount this render target as a UI image element. Returns the new UiElement, or nil if the app has no UI.
Example
local pic = datumhue.image.picture()
image:apply(pic:circfill(32, 32, 24, color("#a7c080")))
-- A second view of the same image, letterboxed and tinted.
image:mount({
width = 192,
height = 96,
fit = "contain",
tint = color("#e69875"),
})
-- Pixel art: a whole number of screen pixels per pixel.
image.filter = "nearest"
image:mount({ width = 128, height = 128, fit = "integer" })
How the texture maps into the element box; aspect-preserving modes center in the box. "sharp" draws with its own shader, so it takes no material; neither "integer" nor "sharp" takes auto_size. "integer" scales a draw canvas's or scene's size in UI px, so on one whose texels are finer than that (a canvas without pixel_perfect on a HiDPI display, a scene) a texel covers a fraction of the multiple. Pair it with the source's filter set to "nearest".
auto_size
boolean
false
For a draw canvas or scene: resize it to the element's size in UI px whenever the element resizes, so what it draws keeps its size in UI px instead of scaling with the element. A scene renders at its own size, so this also keeps one sharp. Raises on a plain image, whose resolution is fixed (use fit).
accessible_label
string
the image has no accessible name
Accessible name for assistive technology. Images carry no text, so unlike text-bearing widgets they derive no name of their own. Set it on images that convey meaning, and decorative on the rest.
decorative
boolean
false
Keeps the image out of what assistive technology reads, as alt="" does on the web: a screen reader passes over it. Set it on an image that only decorates, such as art beside text that says who or what it shows. Setting both this and accessible_label raises, and so does naming the image later.
Wait until this asset is fully loaded, then return it for chaining. An in-memory asset returns at once; one still loading (a file read or remote fetch) yields the coroutine until it lands. A load failure raises; format errors on playable assets still surface at use time.
Decode bytes (PNG, JPEG, WebP, etc.) into the existing pixel buffer in place; the texture refreshes on the next frame. The decoded image must match the image's existing dimensions and pixel format — mismatches raise. Returns the same handle for chaining.
Build a cubemap for a skybox or environment map from this image, which must be six square faces stacked vertically (height == 6 * width, in +X, -X, +Y, -Y, +Z, -Z order). The original image is unchanged. For prefiltered image-based-lighting maps, load a KTX2 cubemap via bytes:cubemap() instead.