Docs / Output format & quality

Output format & quality v0.2.0

f / format picks the output format, and q / quality trades detail for file size. Both are applied at the very end, after sizing, cropping, filters and watermarking.

/photo.png?w=1200&f=avif&q=high
/photo.png?w=1200&f=auto&q=72&meta=icc

Format selection

Set f yourself whenever you need to know exactly what comes back:

jpg jpeg

Still image. Transparency is flattened onto bg.

webp

Still or animated.

png

Still image. Quality decides between palette and lossless encoding.

gif

Still or animated, with a palette.

avif

Still image.

jxl

Still image.

pdf

Document, from a PDF, Office, SVG or vector source.

svg

Document, from an SVG or vector source.

f=pdf and f=svg give you a document rather than an encoded image, so sizing, filters, quality, metadata and output limits don’t apply. If the source can’t produce the format you asked for, you get 415. Documents & vectors covers which sources work, page selection, conversion and the SVG safety settings.

Only WebP and GIF can hold several frames. JPEG, PNG, AVIF and JXL turn an animated source into its first selected frame. See Animation & video for frames, timing, loops and video.

Automatic selection

With f=auto, picturium walks through output.format_priority from left to right and picks the first format whose media type appears in the request’s Accept header. The default order is:

jxl → avif → webp → jpeg → png

If nothing matches, or there’s no usable Accept header, you get WebP. GIF isn’t in the default list, so it’s never picked automatically. Responses with an automatically chosen format carry Vary: Accept; ones with an explicit format don’t.

The matching is simple: it looks for literal media types like image/avif. Wildcards and quality weights aren’t interpreted, so clients using f=auto should list image types explicitly (browsers already do).

output.enable_avif, output.enable_webp and output.enable_jxl exist in the configuration but aren’t used yet. They don’t switch formats off, explicit or automatic.

Quality

q takes low, medium, high, maximum, auto, or a number from 1 to 100. The default is output.quality, which is medium.

  • A number goes straight to the encoder.
  • auto and medium use the format’s quality curve as-is.
  • low, high and maximum add that format’s offset to the curve, then clamp the result to 1–100.

Named levels depend on image size. picturium measures the final image (for animations and documents, a single frame or page). At 0.25 MP or less it uses the curve’s max, at 8 MP or more its min, and anything in between is interpolated.

jpeg
webp
avif
png
jxl
gif

min_area, max_area and every value in the curves can be changed under output.quality_curves. JXL uses the same 1–100 scale as the rest and converts it to a distance internally. PNG switches to lossless encoding at quality 100 by default and uses a palette below that. GIF has no quality setting of its own, so quality controls the palette size, dithering and how much animation frames can be simplified.

/hero.jpg?f=webp&q=medium
/icon.png?f=png&q=100
/gallery/photo.jpg?f=jxl&q=78

Encoder options

Encoder settings are server configuration, not URL parameters. More effort usually means more CPU time for a smaller file.

jpeg
webp

presets by image size, alpha quality, smart subsampling, animation keyframes

png

lossless threshold, compression, dithering

avif

bit depth, codec, encoder, chroma subsampling

jxl

decode speed tier, lossless mode, distance conversion

gif

palette depth, dithering, frame and palette reuse

Every key, range and default is in the output.encoder config reference. output.high_bitdepth and output.cmyk are also reserved and not used by the encoders yet.

Metadata

meta / metadata decides which metadata from the source survives in the output. Separate several values with commas:

none · icc · exif · xmp · iptc · other · gainmap · all

/photo.jpg?f=jpeg&meta=icc,exif
/photo.jpg?f=webp&meta=none

The default comes from output.metadata, which is none. all keeps everything that’s supported. Not every format can store every kind of metadata, and document and original responses ignore this setting.

Output limits

limit / limits caps the output size in pixels, bytes, or both:

/photo.jpg?limit=dimension:1200
/photo.jpg?limit=dimension:1200x800|size:500K
/photo.jpg?limit=dimension:x800|size:1.5MiB
dimension

Scales the result down, keeping proportions, until it fits the given width and/or height.

size

Re-encodes at lower quality when the first encode is too big. Units are binary (1K = 1024 bytes).

Request limits replace the matching output.max_width, output.max_height and output.max_size defaults. A side you don’t mention still gets its configured limit; set the config value to 0 to have no server-wide limit. Because a request can also raise these limits, turn on signed URLs if you rely on them to protect the server.

For a byte limit, picturium makes at most output.max_size_attempts extra attempts and never goes below output.max_size_min_quality. It stops as soon as a result lands within output.max_size_threshold percent under the target. If it can’t get under the target, you get the smallest attempt, even if it’s still too big.

Delivery: download & original

download adds Content-Disposition: attachment. Leave it empty and the filename is the source name with the output’s extension; give it a value and that’s the filename.

/photo.png?f=webp&download
/photo.png?f=webp&download=homepage-image.webp

The filename doesn’t change the format. f still decides what’s actually sent and its Content-Type. Non-ASCII characters, quotes and backslashes in the name are replaced with _.

original=true returns the source file untouched. Format negotiation, sizing, crop, filters, watermarking, quality, metadata and limits are all skipped. You can still combine it with download.

All aliases and defaults are listed in the URL parameter reference.