std/image
The 8-bit Image that std/png and std/jpeg both decode to and encode from, and the operations that make it useful between them: crop, resize, quarter-turn rotations, flips, and oriented for applying a JPEG's EXIF orientation tag.
Pixels are row-major and top-down with channels interleaved bytes each (1 gray, 3 RGB, 4 RGBA) and no row padding, so pixels[(y * width + x) * channels + c] is one sample.
from "std/image" import { Image, ResizeFilter }Example
from "std/fs" import { readFile, writeFile }
// Image.decode picks PNG or JPEG from the file's signature.
let img = Image.decode(readFile("in.jpg")!)!
let square = img.crop(0, 0, img.height, img.height)!
let small = square.resize(256, 256, ResizeFilter.Lanczos3)!
writeFile("out.png", small.rotate90().encodePng()!)!resize is separable and computes its taps the way Pillow does: when shrinking, the kernel widens with the scale so every source pixel contributes, which makes ResizeFilter.Area an exact area average and keeps Bilinear and Lanczos3 from aliasing. Channels are filtered independently, so RGBA is not premultiplied.
API reference
Image
pub struct ImageAn 8-bit image. The methods below assume it is well formed: pixels.len == width * height * channels, which every decoder and method here guarantees for the images it returns.
Fields:
width: i64height: i64channels: i64: 1 (gray), 3 (RGB) or 4 (RGBA)pixels: string: row-major, top-down, channels bytes per pixel, no row padding
Image.crop
fn Image.crop(self: &Image, x: i64, y: i64, w: i64, h: i64): Result<Image, string>The w x h rectangle whose top-left corner is (x, y). Err when the rectangle is empty or reaches outside the image.
Image.decode
fn Image.decode(src: &string): Result<Image, string>Decode a PNG or JPEG, chosen by the file's signature bytes. JPEG EXIF orientation is not applied; see Jpeg.orientation and Image.oriented.
Image.encodePng
fn Image.encodePng(self: &Image): Result<string, string>Encode as PNG (8-bit gray, RGB or RGBA by channel count).
Image.flipHorizontal
fn Image.flipHorizontal(self: &Image): ImageMirrored left to right.
Image.flipVertical
fn Image.flipVertical(self: &Image): ImageMirrored top to bottom.
Image.oriented
fn Image.oriented(self: &Image, orientation: i64): ImageThe image as it should be displayed given an EXIF orientation tag (1-8, as Jpeg.orientation returns): 6 is a camera held upright, stored rotated, and comes back turned 90 degrees clockwise. Values outside 2..8 return an unchanged copy.
Image.resize
fn Image.resize(self: &Image, width: i64, height: i64, filter: ResizeFilter): Result<Image, string>Resample to width x height with filter, separably (rows, then columns). Channels are filtered independently; RGBA is not premultiplied, so a hard alpha edge can pick up the colour of fully transparent neighbours. Err when either target side is not positive.
Image.rotate180
fn Image.rotate180(self: &Image): ImageRotated half a turn.
Image.rotate270
fn Image.rotate270(self: &Image): ImageRotated three quarter turns clockwise, i.e. a quarter turn counter-clockwise.
Image.rotate90
fn Image.rotate90(self: &Image): ImageRotated a quarter turn clockwise (width and height swap).
ResizeFilter
pub enum ResizeFilterThe resampling kernel for Image.resize.
Variants:
Area: Box filter: each output pixel is the area-weighted mean of the source pixels it covers. The right choice for downscaling; upscaling with it is nearest-neighbour.Bilinear: Triangle filter over the 2x2 nearest source pixels (widened to the covered area when downscaling).Lanczos3: Windowed sinc with 3 lobes: sharpest, at the cost of slight ringing on hard edges.