std.image

std.image loads, inspects, saves, and converts images. BMP is always
available (native); PNG and JPEG require libpng/libjpeg at build
time.

Reference

load(path)      # -> {width, height, format, pixels} (pixels: RGBA8 binary)
info(path)      # -> {width, height, format}
save(path, img[, quality = 90])            # img: load()-shaped object
save(path, w, h, pixels[, quality = 90])  # legacy raw-pixel form
convert(in, out[, quality = 90])
capability()    # -> {bmp, png, jpg}
Function Description
load(path) Load image → {width, height, format, pixels}
info(path) Returns {width, height, format} (the file is still fully decoded; only the pixel buffer is omitted)
save(path, img[, q]) Save a load()-shaped {width, height, pixels} object; format from file extension (the object’s format field is informational and ignored)
save(path, w, h, pixels[, q]) Legacy raw-pixel form
convert(in, out[, q]) Convert between formats
capability() Which formats are available

pixels is an RGBA8 binary string of width * height * 4 bytes. quality
(1–100, default 90) affects JPEG output.

Decoded images are capped at 30000 pixels per side and 64M pixels total
(e.g. 30000×30000 exceeds the budget and is rejected).

In guarded engines, load/info need filesystem-read plus native-parse,
save needs filesystem-write, and convert needs all three; missing
capabilities strip the function.

Examples

var caps = std.image.capability()
print(caps.bmp, caps.png, caps.jpg)

var img = std.image.load("photo.png")
print(img.width, "x", img.height, img.format)  # e.g. 800 x 600 png
std.image.save("copy.png", img)
std.image.convert("photo.png", "photo.jpg", 85)

# inspect without decoding everything
var meta = std.image.info("a.jpg")
print(meta.width, meta.format)

Paths accept ~ and $VAR expansion.

See also

  • std.file — file primitives for managing image paths
  • Embedding — image backend auto-detection