Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

imagine.formats

import imagine

imagine exposes this as imagine.formats, so import imagine is enough and the names are called as imagine.formats.*. import imagine.formats reaches the same definitions directly.

What the build can actually read and write, and how to tell one format from another.

detect() and probe() identify an image from its leading bytes rather than its file name, which is the only reliable way to do it. readable(), writable() and animatable() report what this particular build supports, since that depends on which codecs were compiled in.

Functions

from_extension()

imagine.formats.from_extension(path: string) -> ?string

The format name a file extension implies, or nil when the extension is not one this module knows.

The argument may be a bare extension or a whole path, with or without a leading dot, in any case.

%> imagine.formats.from_extension('photo.JPG')
'jpeg'
%> imagine.formats.from_extension('.webp')
'webp'

Parameters

  • path (string)

Returns ?string

extension_for()

imagine.formats.extension_for(format: string) -> string

The file extension a format is normally written with, without a leading dot.

Parameters

  • format (string)

Returns string

Raises FormatError When format is not a known format.

mime_for()

imagine.formats.mime_for(format: string) -> string

The IANA media type for a format, suitable for a Content-Type header.

Parameters

  • format (string)

Returns string

Raises FormatError When format is not a known format.

normalize()

imagine.formats.normalize(format: string) -> string

Normalises a format name, accepting the common aliases.

'JPG', 'jpeg' and '.jpg' all come back as 'jpeg'.

Parameters

  • format (string)

Returns string

Raises FormatError When format is not a known format.

detect()

imagine.formats.detect(data: bytes) -> ?string

Identifies image data by its content rather than its name, or returns nil when the bytes are not a recognisable image.

This reads only as much of the header as it needs, so it is cheap enough to run over an upload before deciding whether to decode it.

var kind = imagine.formats.detect(upload)

if kind == nil {
  raise Exception('that is not an image')
}

Parameters

  • data (bytes)

Returns ?string

probe()

imagine.formats.probe(data: bytes) -> ?dict

Reads an image’s format and dimensions without decoding its pixels.

Returns a dictionary holding format, width and height, or nil when the data is not a recognisable image. Reading a multi-megapixel JPEG’s header costs a few microseconds where decoding it costs tens of milliseconds, so this is the right way to reject an oversized upload before committing to it.

Parameters

  • data (bytes)

Returns ?dict

readable()

imagine.formats.readable() -> list

Every format this build can read.

Returns list

writable()

imagine.formats.writable() -> list

Every format this build can write.

Returns list

animatable()

imagine.formats.animatable() -> list

Every format this build can read as an animation.

Returns list

decode_wbmp()

imagine.formats.decode_wbmp(data: bytes)

Decodes a WBMP into straight RGBA pixels.

Set bits become opaque white and clear bits opaque black; the format has no colour and no transparency.

Parameters

  • data (bytes)

Returns — dict: pixels, width, height.

Raises DecodeError When the data is not a well-formed WBMP.

encode_wbmp()

imagine.formats.encode_wbmp(pixels: bytes, width: number, height: number, threshold: ?number) -> bytes

Encodes straight RGBA pixels as a WBMP.

Each pixel is reduced to one bit by comparing its perceived brightness against threshold. Transparent pixels are treated as white, since the format has no way to say “nothing here” and white is what a viewer will show as background.

Parameters

  • pixels (bytes)
  • width (number)
  • height (number)
  • threshold (?number) — The brightness cut, 0-255 - Default: 128.

Returns bytes


2026, Richard Ore and Zuri contributors