API Reference
Complete API documentation for @cross/image.
Image Class
The main class for working with images.
Static Methods
Image.decode(data: Uint8Array, formatOrOptions?: string | ImageDecoderOptions, options?: ImageDecoderOptions): Promise<Image>
Decode an image from bytes. Automatically detects format if not specified.
Supports these call forms:
Image.decode(data)Image.decode(data, "jpeg")Image.decode(data, { tolerantDecoding, onWarning, runtimeDecoding })Image.decode(data, "jpeg", { ...options })
Parameters:
data- Raw image data as Uint8ArrayformatOrOptions- Optional format hint (e.g., "png", "jpeg", "webp") or anImageDecoderOptionsobjectoptions- OptionalImageDecoderOptions(when passing an explicit format string)
Returns: Promise that resolves to an Image instance
Example:
// Deno
const data = await Deno.readFile("input.png");
const image = await Image.decode(data);
// Strict decoding (fail fast)
const strict = await Image.decode(data, { tolerantDecoding: false });
// Node.js
// import { readFile } from "node:fs/promises";
// const data = await readFile("input.png");
// const image = await Image.decode(data);
Image.read(data: Uint8Array, format?: string): Promise<Image> ⚠️ Deprecated
Deprecated: Use decode() instead. This method will be removed in a future version.
Read an image from bytes. Automatically detects format if not specified.
Image.decodeFrames(data: Uint8Array, formatOrOptions?: string | ImageDecoderOptions, options?: ImageDecoderOptions): Promise<MultiFrameImageData>
Decode all frames from a multi-frame image (animated GIF or multi-page TIFF).
Supports these call forms:
Image.decodeFrames(data)Image.decodeFrames(data, "gif")Image.decodeFrames(data, { tolerantDecoding, onWarning, runtimeDecoding })Image.decodeFrames(data, "gif", { ...options })
Parameters:
data- Raw image data as Uint8ArrayformatOrOptions- Optional format hint (e.g., "gif", "tiff") or anImageDecoderOptionsobjectoptions- OptionalImageDecoderOptions(when passing an explicit format string)
Returns: Promise that resolves to MultiFrameImageData with all frames
Example:
// Deno
const gifData = await Deno.readFile("animated.gif");
const multiFrame = await Image.decodeFrames(gifData);
// Strict decoding (fail fast)
const strictFrames = await Image.decodeFrames(gifData, {
tolerantDecoding: false,
});
// Node.js
// import { readFile } from "node:fs/promises";
// const gifData = await readFile("animated.gif");
// const multiFrame = await Image.decodeFrames(gifData);
console.log(`Number of frames: ${multiFrame.frames.length}`);
Image.readFrames(data: Uint8Array, format?: string): Promise<MultiFrameImageData> ⚠️ Deprecated
Deprecated: Use decodeFrames() instead. This method will be removed in a future version.
Read all frames from a multi-frame image (animated GIF or multi-page TIFF).
Image.encodeFrames(format: string, imageData: MultiFrameImageData, options?: unknown): Promise<Uint8Array>
Encode multi-frame image data to bytes in the specified format.
Parameters:
format- Format name (e.g., "gif", "tiff")imageData- Multi-frame image data to encodeoptions- Optional format-specific encoding options
Returns: Promise that resolves to encoded image bytes
Example:
const tiffData = await Image.encodeFrames("tiff", multiPageTiff, {
compression: "lzw",
});
Image.saveFrames(format: string, imageData: MultiFrameImageData, options?: unknown): Promise<Uint8Array> ⚠️ Deprecated
Deprecated: Use encodeFrames() instead. This method will be removed in a future version.
Save multi-frame image data to bytes in the specified format.
Image.fromRGBA(width: number, height: number, data: Uint8Array): Image
Create an image from raw RGBA data.
Parameters:
width- Image width in pixelsheight- Image height in pixelsdata- Raw RGBA pixel data (width * height * 4 bytes)
Returns: New Image instance
Example:
const data = new Uint8Array(100 * 100 * 4); // 100x100 red square
for (let i = 0; i < data.length; i += 4) {
data[i] = 255; // R
data[i + 3] = 255; // A
}
const image = Image.fromRGBA(100, 100, data);
Image.create(width: number, height: number, r?: number, g?: number, b?: number, a?: number): Image
Create a blank image with the specified dimensions and color.
Parameters:
width- Image width in pixelsheight- Image height in pixelsr- Red component (0-255, default: 0)g- Green component (0-255, default: 0)b- Blue component (0-255, default: 0)a- Alpha component (0-255, default: 255)
Returns: New Image instance
Example:
// Create a 400x300 white canvas
const canvas = Image.create(400, 300, 255, 255, 255);
// Create a 200x200 transparent canvas
const transparent = Image.create(200, 200, 0, 0, 0, 0);
Image.registerFormat(format: ImageFormat): void
Register a custom format handler.
Parameters:
format- Custom format implementation
Example:
Image.registerFormat(new MyCustomFormat());
Image.getFormats(): readonly ImageFormat[]
Get all registered format handlers.
Returns: Read-only array of registered format handlers
Image.getSupportedMetadata(format: string): Array<keyof ImageMetadata> | undefined
Get supported metadata fields for a specific format.
Parameters:
format- Format name (e.g., "jpeg", "png", "webp")
Returns: Array of supported metadata field names, or undefined if format doesn't support metadata
Example:
const jpegFields = Image.getSupportedMetadata("jpeg");
console.log(jpegFields);
// Includes: cameraMake, cameraModel, iso, exposureTime, fNumber, etc.
const pngFields = Image.getSupportedMetadata("png");
console.log(pngFields);
// Includes: title, description, author, dpiX, dpiY, latitude, longitude, etc.
Image.extractMetadata(data: Uint8Array, format?: string): Promise<ImageMetadata | undefined>
Extract metadata from image data without fully decoding the pixel data. This is useful for quickly reading EXIF, XMP, or other metadata from images that may have unsupported features or compression methods.
Parameters:
data- Raw image dataformat- Optional format hint (e.g., "jpeg", "png", "webp")
Returns: Promise that resolves to metadata extracted from the image, or undefined if extraction fails or format is unsupported
Example:
// Extract metadata without decoding pixels (faster)
const data = await Deno.readFile("large-photo.jpg");
const metadata = await Image.extractMetadata(data);
console.log(metadata?.cameraMake); // "Canon"
console.log(metadata?.iso); // 800
console.log(metadata?.exposureTime); // 0.004
// Works with auto-detection or explicit format
const metadata2 = await Image.extractMetadata(data, "jpeg");
Image.extractCoefficients(data: Uint8Array, format?: string, options?: ImageDecoderOptions): Promise<CoefficientData | undefined>
Extract quantized DCT coefficients from encoded image data. Currently supports JPEG format. This is useful for frequency-domain processing and steganography applications.
Parameters:
data- Raw image dataformat- Optional format hint (e.g., "jpeg")options- Optional decoder options
Returns: Promise that resolves to coefficient data, or undefined if extraction fails or format is unsupported
Example:
const data = await Deno.readFile("photo.jpg");
const coefficients = await Image.extractCoefficients(data, "jpeg");
if (coefficients) {
console.log(`Image: ${coefficients.width}x${coefficients.height}`);
console.log(`Components: ${coefficients.components.length}`);
// Access DCT coefficient blocks
for (const comp of coefficients.components) {
for (const row of comp.blocks) {
for (const block of row) {
// block is Int32Array[64] in zigzag order
const dcCoeff = block[0]; // DC coefficient
// block[1..63] are AC coefficients
}
}
}
}
Image.encodeFromCoefficients(coefficients: CoefficientData, format?: string, options?: unknown): Promise<Uint8Array>
Encode an image from coefficient data. Currently supports JPEG format. This allows re-encoding modified coefficients back to a valid image file.
Parameters:
coefficients- Coefficient data (e.g., fromextractCoefficients)format- Optional format hint (auto-detected from coefficient data if not provided)options- Optional format-specific encoding options
Returns: Promise that resolves to encoded image bytes
Example:
const data = await Deno.readFile("input.jpg");
const coefficients = await Image.extractCoefficients(data, "jpeg");
if (coefficients) {
// Modify coefficients (e.g., for steganography)
for (const comp of coefficients.components) {
for (const row of comp.blocks) {
for (const block of row) {
// Modify AC coefficient LSBs
if (block[1] !== 0 && Math.abs(block[1]) > 1) {
block[1] = block[1] & ~1; // Clear LSB
}
}
}
}
// Re-encode to JPEG
const encoded = await Image.encodeFromCoefficients(coefficients, "jpeg");
await Deno.writeFile("output.jpg", encoded);
}
Instance Properties
width: number (read-only)
Image width in pixels.
height: number (read-only)
Image height in pixels.
data: Uint8Array (read-only)
Raw RGBA pixel data (4 bytes per pixel, in row-major order).
metadata: ImageMetadata | undefined (read-only)
Optional image metadata including DPI, GPS coordinates, title, description, etc.
Instance Methods
resize(options: ResizeOptions): this
Resize the image in-place. Returns this for method chaining.
Parameters:
options- Resize configuration object
Returns: this for chaining
Example:
image.resize({ width: 800, height: 600 });
// or with nearest neighbor
image.resize({ width: 400, height: 300, method: "nearest" });
encode(format: string, options?: unknown): Promise<Uint8Array>
Encode image to bytes in the specified format with optional format-specific options.
Parameters:
format- Format name (e.g., "png", "jpeg", "webp")options- Optional format-specific encoding options
Returns: Promise that resolves to encoded image bytes
Example:
const png = await image.encode("png");
const jpeg = await image.encode("jpeg", { quality: 90 });
const progressiveJpeg = await image.encode("jpeg", {
quality: 90,
progressive: true,
});
save(format: string, options?: unknown): Promise<Uint8Array> ⚠️ Deprecated
Deprecated: Use encode() instead. This method will be removed in a future version.
Save image to bytes in the specified format with optional format-specific options.
clone(): Image
Create a deep copy of the image.
Returns: New Image instance with copied data
Example:
const copy = image.clone();
setMetadata(metadata: ImageMetadata, merge?: boolean): this
Set or update image metadata. Returns this for method chaining.
Parameters:
metadata- Metadata to set or mergemerge- If true (default), merges with existing metadata. If false, replaces it.
Returns: this for chaining
getMetadataField<K>(key: K): ImageMetadata[K] | undefined
Get a specific metadata field value.
Parameters:
key- The metadata field name to retrieve
Returns: The metadata value or undefined if not set
getPosition(): { latitude: number; longitude: number } | undefined
Get GPS position from metadata.
Returns: Object with latitude and longitude, or undefined if not available
setPosition(latitude: number, longitude: number): this
Set GPS position in metadata. Returns this for method chaining.
Parameters:
latitude- GPS latitudelongitude- GPS longitude
Returns: this for chaining
getDimensions(): { dpiX?: number; dpiY?: number; physicalWidth?: number; physicalHeight?: number } | undefined
Get physical dimensions from metadata.
Returns: Object with DPI and physical dimensions, or undefined if not available
setDPI(dpiX: number, dpiY?: number): this
Set DPI and calculate physical dimensions. Returns this for method chaining.
Parameters:
dpiX- Dots per inch (horizontal)dpiY- Dots per inch (vertical), defaults to dpiX if not provided
Returns: this for chaining
composite(overlay: Image, x: number, y: number, opacity?: number): this
Composite another image on top of this image at the specified position.
Parameters:
overlay- Image to place on topx- X position (can be negative)y- Y position (can be negative)opacity- Opacity of overlay (0-1, default: 1)
Returns: this for chaining
Example:
const background = Image.create(800, 600, 255, 255, 255);
const logo = await Image.decode(await Deno.readFile("logo.png"));
background.composite(logo, 10, 10, 0.8);
brightness(amount: number): this
Adjust the brightness of the image.
Parameters:
amount- Brightness adjustment (-1 to 1, where 0 is no change)
Returns: this for chaining
Example:
image.brightness(0.2); // Increase brightness by 20%
image.brightness(-0.1); // Decrease brightness by 10%
contrast(amount: number): this
Adjust the contrast of the image.
Parameters:
amount- Contrast adjustment (-1 to 1, where 0 is no change)
Returns: this for chaining
Example:
image.contrast(0.3); // Increase contrast
image.contrast(-0.2); // Decrease contrast
exposure(amount: number): this
Adjust the exposure of the image in photographic stops.
Parameters:
amount- Exposure adjustment in stops (-3 to 3, where 0 is no change)
Returns: this for chaining
Example:
image.exposure(1); // Increase exposure by 1 stop (2x brighter)
image.exposure(-1); // Decrease exposure by 1 stop (0.5x darker)
saturation(amount: number): this
Adjust the color saturation of the image.
Parameters:
amount- Saturation adjustment (-1 to 1, where 0 is no change, -1 is grayscale)
Returns: this for chaining
Example:
image.saturation(0.5); // Increase saturation
image.saturation(-0.3); // Desaturate
image.saturation(-1); // Full grayscale (same as image.grayscale())
hue(degrees: number): this
Adjust the hue of the image by rotating the color wheel.
Parameters:
degrees- Hue rotation in degrees. Any value is accepted and wraps at 360 degrees. Positive values rotate clockwise, negative values rotate counter-clockwise. 0 means no change.
Returns: this for chaining
Example:
image.hue(30); // Shift colors towards yellow/orange
image.hue(120); // Shift reds to greens, greens to blues, blues to reds
image.hue(-60); // Shift colors towards blue/purple
Use Cases:
- Color correction (e.g., adjusting skin tones, sky colors)
- Creative color grading effects
- Fixing white balance issues
- Seasonal color shifts (autumn/spring effects)
invert(): this
Invert all colors in the image (negative effect).
Returns: this for chaining
Example:
image.invert(); // Create a color negative
grayscale(): this
Convert the image to grayscale.
Returns: this for chaining
Example:
image.grayscale(); // Convert to black and white
sepia(): this
Apply a sepia tone effect to the image, giving it a warm, brownish, vintage appearance.
Returns: this for chaining
Example:
image.sepia(); // Apply vintage sepia tone effect
blur(radius?: number): this
Apply a box blur filter to the image.
Parameters:
radius- Blur radius (default: 1). Higher values create stronger blur.
Returns: this for chaining
Example:
image.blur(); // Light blur with default radius
image.blur(3); // Stronger blur effect
gaussianBlur(radius?: number, sigma?: number): this
Apply a Gaussian blur filter to the image. Gaussian blur provides more natural, edge-preserving results compared to box blur.
Parameters:
radius- Blur radius (default: 1)sigma- Optional standard deviation for the Gaussian kernel. If not provided, calculated from radius (radius / 3)
Returns: this for chaining
Example:
image.gaussianBlur(); // Natural blur with default parameters
image.gaussianBlur(2); // Medium blur
image.gaussianBlur(3, 1.5); // Custom blur with specific sigma
sharpen(amount?: number): this
Apply a sharpening filter to enhance edges and details in the image.
Parameters:
amount- Sharpening amount (0 to 1, default: 0.5). Higher values create stronger sharpening.
Returns: this for chaining
Example:
image.sharpen(); // Moderate sharpening
image.sharpen(0.3); // Light sharpening
image.sharpen(0.8); // Strong sharpening
medianFilter(radius?: number): this
Apply a median filter to reduce noise, especially effective for salt-and-pepper noise while preserving edges.
Parameters:
radius- Filter radius (default: 1). Higher values provide stronger noise reduction but slower processing.
Returns: this for chaining
Example:
image.medianFilter(); // Light noise reduction
image.medianFilter(2); // Stronger noise reduction
fillRect(x: number, y: number, width: number, height: number, r: number, g: number, b: number, a?: number): this
Fill a rectangular region with a solid color.
Parameters:
x- Starting X positiony- Starting Y positionwidth- Width of the fill regionheight- Height of the fill regionr- Red component (0-255)g- Green component (0-255)b- Blue component (0-255)a- Alpha component (0-255, default: 255)
Returns: this for chaining
Example:
const canvas = Image.create(400, 300, 255, 255, 255);
canvas.fillRect(50, 50, 100, 100, 255, 0, 0); // Red rectangle
canvas.fillRect(200, 100, 150, 80, 0, 0, 255, 128); // Semi-transparent blue
crop(x: number, y: number, width: number, height: number): this
Crop the image to a rectangular region.
Parameters:
x- Starting X positiony- Starting Y positionwidth- Width of the crop regionheight- Height of the crop region
Returns: this for chaining
Example:
image.crop(100, 100, 200, 150); // Crop to 200x150 region starting at (100, 100)
getPixel(x: number, y: number): { r: number; g: number; b: number; a: number } | undefined
Get the color of a pixel at the specified position.
Parameters:
x- X positiony- Y position
Returns: Object with r, g, b, a components (0-255) or undefined if out of bounds
Example:
const color = image.getPixel(50, 100);
if (color) {
console.log(
`Pixel color: rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`,
);
}
setPixel(x: number, y: number, r: number, g: number, b: number, a?: number): this
Set the color of a pixel at the specified position.
Parameters:
x- X positiony- Y positionr- Red component (0-255)g- Green component (0-255)b- Blue component (0-255)a- Alpha component (0-255, default: 255)
Returns: this for chaining
Example:
image.setPixel(50, 100, 255, 0, 0); // Set pixel to red
image.setPixel(51, 100, 0, 255, 0, 128); // Set pixel to semi-transparent green
rotate(degrees: number): this
Rotate the image by the specified angle in degrees. Rotations are rounded to the nearest 90-degree increment.
Parameters:
degrees- Rotation angle in degrees (positive = clockwise, negative = counter-clockwise)
Returns: this for chaining
Example:
image.rotate(90); // Rotate 90° clockwise
image.rotate(-90); // Rotate 90° counter-clockwise
image.rotate(180); // Rotate 180°
image.rotate(45); // Rotate 45° clockwise (rounded to nearest 90°)
rotate90(): this
Rotate the image 90 degrees clockwise.
Returns: this for chaining
Example:
image.rotate90(); // Rotate 90° clockwise
rotate180(): this
Rotate the image 180 degrees.
Returns: this for chaining
Example:
image.rotate180(); // Flip upside down
rotate270(): this
Rotate the image 270 degrees clockwise (or 90 degrees counter-clockwise).
Returns: this for chaining
Example:
image.rotate270(); // Rotate 90° counter-clockwise
flipHorizontal(): this
Flip the image horizontally (mirror effect).
Returns: this for chaining
Example:
image.flipHorizontal(); // Create horizontal mirror
flipVertical(): this
Flip the image vertically.
Returns: this for chaining
Example:
image.flipVertical(); // Flip upside down
Type Definitions
ResizeOptions
Configuration for image resizing.
interface ResizeOptions {
/** Target width in pixels */
width: number;
/** Target height in pixels */
height: number;
/** Resize algorithm (default: "bilinear") */
method?: "nearest" | "bilinear" | "bicubic";
/** Fitting mode (default: "stretch") */
fit?: "stretch" | "fit" | "fill" | "cover" | "contain";
}
Resize methods:
bilinear- Smooth interpolation, better quality (default)nearest- Fast pixel sampling, pixelated resultbicubic- High-quality cubic interpolation, best quality (slowest)
Fitting modes:
stretch- Stretch image to fill dimensions (may distort) (default)fit/contain- Fit image within dimensions maintaining aspect ratio (may have letterboxing)fill/cover- Fill dimensions maintaining aspect ratio (may crop)
ASCIIEncoderOptions
Configuration for ASCII art encoding.
interface ASCIIEncoderOptions {
/** Target width in characters (default: 80) */
width?: number;
/** Character set to use (default: "simple") */
charset?: "simple" | "extended" | "blocks" | "detailed";
/** Aspect ratio correction factor for terminal display (default: 0.5) */
aspectRatio?: number;
/** Whether to invert brightness (default: false) */
invert?: boolean;
}
Character sets:
simple- 10 characters (.:-=+*#%@) - good for basic artextended- 70 characters - detailed gradientsblocks- 5 block characters (░▒▓█) - smooth gradientsdetailed- 92 characters - maximum detail
WebPEncoderOptions
Configuration for WebP encoding.
interface WebPEncoderOptions {
/** Encoding quality 1-100 (default: 90) */
quality?: number;
/** Force lossless encoding even with quality < 100 (default: false) */
lossless?: boolean;
}
Quality levels:
100- Lossless encoding (VP8L without quantization)90-99- Very high quality with minimal quantization70-89- High quality with light quantization50-69- Medium quality with noticeable quantization30-49- Lower quality with heavy quantization1-29- Low quality with very heavy quantization
Note: When OffscreenCanvas is available (Deno, modern browsers, Bun), the runtime's native WebP encoder is used for better compression. In pure-JS mode (Node.js without OffscreenCanvas), VP8L format with quality-based color quantization is used.
TIFFEncoderOptions
Configuration for TIFF encoding.
interface TIFFEncoderOptions {
/** Compression method: "none" (default), "lzw", "packbits", or "deflate" */
compression?: "none" | "lzw" | "packbits" | "deflate";
/** Encode as grayscale instead of RGB/RGBA (default: false) */
grayscale?: boolean;
/** Encode as RGB without alpha channel (default: false, ignored if grayscale is true) */
rgb?: boolean;
}
Compression methods:
none- Uncompressed TIFF (larger file size, fastest encoding)lzw- LZW compression (smaller file size, lossless)packbits- PackBits RLE compression (lossless)deflate- Deflate compression (lossless)
Color modes:
- Default: RGBA with alpha channel
grayscale: true- Convert to grayscalergb: true- RGB without alpha channel (smaller file size if transparency not needed)
JPEGEncoderOptions
Configuration for JPEG encoding.
interface JPEGEncoderOptions {
/** Encoding quality (1-100) */
quality?: number;
/** Progressive JPEG output (pure-JS encoder only) */
progressive?: boolean;
}
PNGEncoderOptions
Configuration for PNG encoding.
interface PNGEncoderOptions {
/** Compression level (0-9, default: 6) */
compressionLevel?: number;
}
Compression levels:
0- No filtering, fastest encoding1-2- Fast (no filtering)3-6- Balanced (Sub filter)7-9- Best compression (adaptive filtering per scanline)
The compression level controls PNG filter selection, which significantly affects compression efficiency. Higher levels produce smaller files but take longer to encode.
Example:
// Fast encoding
const pngFast = await image.encode("png", { compressionLevel: 0 });
// Balanced (default)
const pngBalanced = await image.encode("png", { compressionLevel: 6 });
// Best compression
const pngBest = await image.encode("png", { compressionLevel: 9 });
APNGEncoderOptions
Configuration for APNG (Animated PNG) encoding.
interface APNGEncoderOptions extends PNGEncoderOptions {
/** Compression level (0-9, default: 6) - inherited from PNGEncoderOptions */
compressionLevel?: number;
}
Note: APNG uses PNG encoding for each frame and supports the same compression levels.
GIFEncoderOptions
Configuration for GIF encoding.
interface GIFEncoderOptions {
/** Loop count for animated GIFs (0 = infinite, 1+ = specific count) */
loop?: number;
}
Loop count:
0(default) - Loop infinitely1+- Loop a specific number of timesundefined- Same as 0 (infinite loop)
Example:
// Infinite loop (default)
const gif = await Image.encodeFrames("gif", multiFrame);
// Loop 3 times then stop
const gifLoopThree = await Image.encodeFrames("gif", multiFrame, { loop: 3 });
// Single play (no loop)
const gifOnce = await Image.encodeFrames("gif", multiFrame, { loop: 1 });
AVIFEncoderOptions
Configuration for AVIF encoding.
interface AVIFEncoderOptions {
/** Best-effort encoding quality (0-1 or 1-100) */
quality?: number;
}
Note: AVIF encoding is delegated to runtime APIs (OffscreenCanvas). Many runtimes ignore quality or may not support AVIF encoding at all.
HEICEncoderOptions
Configuration for HEIC encoding.
interface HEICEncoderOptions {
/** Best-effort encoding quality (0-1 or 1-100) */
quality?: number;
}
Note: HEIC encoding is delegated to runtime APIs (OffscreenCanvas). Many runtimes do not support HEIC encoding.
ImageData
Represents decoded image data.
interface ImageData {
/** Image width in pixels */
width: number;
/** Image height in pixels */
height: number;
/** Raw RGBA pixel data (4 bytes per pixel) */
data: Uint8Array;
/** Optional metadata */
metadata?: ImageMetadata;
}
MultiFrameImageData
Represents multi-frame image data (animated GIF, multi-page TIFF).
interface MultiFrameImageData {
/** Canvas width in pixels */
width: number;
/** Canvas height in pixels */
height: number;
/** Array of frames */
frames: ImageFrame[];
/** Optional global metadata */
metadata?: ImageMetadata;
}
ImageFrame
Represents a single frame in a multi-frame image.
interface ImageFrame {
/** Frame width in pixels */
width: number;
/** Frame height in pixels */
height: number;
/** Raw RGBA pixel data (4 bytes per pixel) */
data: Uint8Array;
/** Optional frame-specific metadata */
frameMetadata?: FrameMetadata;
}
FrameMetadata
Frame-specific metadata for animations.
interface FrameMetadata {
/** Frame delay in milliseconds (for animations) */
delay?: number;
/** Frame disposal method */
disposal?: "none" | "background" | "previous";
/** X offset of frame within canvas */
left?: number;
/** Y offset of frame within canvas */
top?: number;
}
Disposal methods:
none- Do nothing (leave frame as-is)background- Clear to background color before next frameprevious- Restore to previous frame state
ImageMetadata
General image metadata.
interface ImageMetadata {
/** Physical width in inches (derived from DPI if available) */
physicalWidth?: number;
/** Physical height in inches (derived from DPI if available) */
physicalHeight?: number;
/** Dots per inch (horizontal) */
dpiX?: number;
/** Dots per inch (vertical) */
dpiY?: number;
/** GPS latitude */
latitude?: number;
/** GPS longitude */
longitude?: number;
/** Image title */
title?: string;
/** Image description */
description?: string;
/** Image author */
author?: string;
/** Copyright information */
copyright?: string;
/** Creation date */
creationDate?: Date;
/** Custom metadata fields */
custom?: Record<string, string | number | boolean>;
}
ImageDecoderOptions
Common options for the decode APIs.
interface ImageDecoderOptions {
/**
* Controls tolerant decoding in the pure-JS decoders.
*
* - true (default): try to recover from corruption and continue
* - false: strict mode (fail fast)
*/
tolerantDecoding?: boolean;
/**
* Optional warning callback used by pure-JS decoders when non-fatal issues
* are encountered.
*/
onWarning?: (message: string, details?: unknown) => void;
/**
* Runtime decoder strategy.
*
* - "prefer" (default): try runtime decoders first (ImageDecoder/Canvas), then fall back to pure JS
* - "never": skip runtime decoders and use pure JS when available
*/
runtimeDecoding?: "prefer" | "never";
}
JPEGQuantizedCoefficients
JPEG quantized DCT coefficients for frequency-domain processing and steganography.
interface JPEGQuantizedCoefficients {
/** Format identifier */
format: "jpeg";
/** Image width in pixels */
width: number;
/** Image height in pixels */
height: number;
/** Whether the JPEG is progressive */
isProgressive: boolean;
/** Component data (Y, Cb, Cr for color images) */
components: JPEGComponentCoefficients[];
/** Quantization tables used (indexed by table ID) */
quantizationTables: (Uint8Array | number[])[];
/** MCU width (number of 8x8 blocks horizontally) */
mcuWidth: number;
/** MCU height (number of 8x8 blocks vertically) */
mcuHeight: number;
}
JPEGComponentCoefficients
Coefficients for a single JPEG component (Y, Cb, or Cr).
interface JPEGComponentCoefficients {
/** Component ID (1=Y, 2=Cb, 3=Cr typically) */
id: number;
/** Horizontal sampling factor */
h: number;
/** Vertical sampling factor */
v: number;
/** Quantization table index */
qTable: number;
/**
* Quantized DCT coefficient blocks
* blocks[blockRow][blockCol] contains a 64-element Int32Array in zigzag order
* Coefficients are quantized (divided by quantization table values)
*/
blocks: Int32Array[][];
}
CoefficientData
Union type for coefficient data from different formats. Currently only JPEG is supported.
type CoefficientData = JPEGQuantizedCoefficients;
ImageFormat
Interface for custom format handlers.
interface ImageFormat {
/** Format name (e.g., "png", "jpeg", "webp") */
readonly name: string;
/** MIME type (e.g., "image/png") */
readonly mimeType: string;
/**
* Decode image data from bytes
* @param data Raw image data
* @param options Optional `ImageDecoderOptions`
* @returns Decoded image data
*/
decode(data: Uint8Array, options?: ImageDecoderOptions): Promise<ImageData>;
/**
* Encode image data to bytes
* @param imageData Image data to encode
* @param options Optional format-specific encoding options
* @returns Encoded image bytes
*/
encode(
imageData: ImageData,
options?: unknown,
): Promise<Uint8Array>;
/**
* Check if the given data is in this format
* @param data Raw data to check
* @returns true if the data matches this format
*/
canDecode(data: Uint8Array): boolean;
/**
* Decode all frames from multi-frame image (optional)
* @param data Raw image data
* @param options Optional `ImageDecoderOptions`
* @returns Decoded multi-frame image data
*/
decodeFrames?(
data: Uint8Array,
options?: ImageDecoderOptions,
): Promise<MultiFrameImageData>;
/**
* Encode multi-frame image data to bytes (optional)
* @param imageData Multi-frame image data to encode
* @param options Optional format-specific encoding options
* @returns Encoded image bytes
*/
encodeFrames?(
imageData: MultiFrameImageData,
options?: unknown,
): Promise<Uint8Array>;
/**
* Check if the format supports multiple frames
*/
supportsMultipleFrames?(): boolean;
/**
* Get the list of metadata fields supported by this format
*/
getSupportedMetadata?(): Array<keyof ImageMetadata>;
/**
* Extract metadata from image data without fully decoding the pixel data
*/
extractMetadata?(data: Uint8Array): Promise<ImageMetadata | undefined>;
}
Exported Format Classes
The library exports format classes that can be used for advanced scenarios:
PNGFormat- PNG format handlerAPNGFormat- Animated PNG format handlerJPEGFormat- JPEG format handlerWebPFormat- WebP format handlerGIFFormat- GIF format handlerTIFFFormat- TIFF format handlerBMPFormat- BMP format handlerICOFormat- ICO/CUR format handlerDNGFormat- DNG format handlerPAMFormat- PAM format handlerPCXFormat- PCX format handlerPPMFormat- PPM format handlerASCIIFormat- ASCII art format handlerHEICFormat- HEIC/HEIF format handlerAVIFFormat- AVIF format handler
Most users should use the Image class methods instead. The format classes are useful when you want
to:
- Use a handler directly (
format.decode(...),format.encode(...)) without the higher-levelImageconvenience APIs. - Register a custom format implementation via
Image.registerFormat(...).
Example: Use a format handler directly
import { PNGFormat } from "jsr:@cross/image";
const png = new PNGFormat();
const data = await Deno.readFile("input.png");
const decoded = await png.decode(data, { tolerantDecoding: false });
// `decoded` is an ImageData structure; you can re-encode it directly.
const out = await png.encode(decoded);
await Deno.writeFile("roundtrip.png", out);
Example: Register a custom format
import type { ImageData, ImageFormat } from "jsr:@cross/image";
import { Image } from "jsr:@cross/image";
class MyFormat implements ImageFormat {
readonly name = "myfmt";
readonly mimeType = "application/x-myfmt";
canDecode(data: Uint8Array): boolean {
return data.length >= 4 && data[0] === 0x4d && data[1] === 0x59;
}
async decode(_data: Uint8Array): Promise<ImageData> {
throw new Error("Not implemented");
}
async encode(_imageData: ImageData): Promise<Uint8Array> {
throw new Error("Not implemented");
}
}
Image.registerFormat(new MyFormat());