Skip to main content

Image output

output() produces one transformed image: keep or change the format, and set quality, target size, resize and the other route-honored controls along the way.

It is the single image-transform verb. You do not pick an operation — the SDK resolves the route from your input format and requested output format:

  • Same format (or no format given) → the optimiser route.
  • Format change → the transcoder route.

How much the SDK checks for you depends on the kind of mistake:

  • An option key no image route recognises is rejected as soon as you call output(), before any upload.
  • A real key that the resolved route does not honor (for example progressive on a format change) is caught when the recipe lowers, which both SDKs run before the upload — a route-invalid option never costs you bytes.
  • A value outside the option's enum (for example metadata: 'keep' on AVIF or SVG) is caught before upload on the same-format route — the SDK checks the requested value against the format's accepted enum, not just the contract's planned markers.
// Omit the format to keep the input format.
const result = await client
.file('photo.jpg')
.output(undefined, { quality: 80 })
.run({ maxWait: '2m' });

// Or change format.
const webp = await client
.file('photo.jpg')
.output('webp', { quality: 80 })
.run({ maxWait: '2m' });

Hitting a target size

Set encoding_mode: 'target_size' and give target_size_bytes (minimum 1024). The encoder aims for that size instead of a quality slider. Honored on same-format avif, jpeg and webp.

const result = await client
.file('photo.jpg')
.output(undefined, {
encoding_mode: 'target_size',
target_size_bytes: 200 * 1024,
})
.run({ maxWait: '2m' });
note

target_size_bytes is in bytes. For "200 KB", write 200 * 1024.

Resizing

resize() is part of the output transform, not a separate artifact — it merges into the preceding output() step, so you get one image out. If nothing precedes it, it adds a same-format output step carrying the resize. It never emits a thumbnail.

Height is optional; width-only preserves the aspect ratio. fit takes max, crop or scale.

// Width-only — aspect ratio preserved.
await client.file('photo.jpg').resize(1200).run({ maxWait: '2m' });

// Merged into the output() step — still one artifact.
await client
.file('photo.jpg')
.output('webp', { quality: 80 })
.resize(1200, 800, 'crop')
.run({ maxWait: '2m' });

You can equally pass width / height / fit straight to output() — same result, same single operation.

Resize is raster-only. A vector input such as SVG has no resize on its route and throws when the recipe lowers.

Stripping metadata

metadata defaults to strip. Pass keep to preserve EXIF and friends on same-format jpeg, png, webp, gif and tiff. On a format change it is planned, so asking for it there is rejected rather than silently keeping metadata.

note

keep is not offered for AVIF or SVG — AVIF is re-encoded from pixels and SVG is optimised as markup, so neither can carry the original metadata through. Those routes accept strip only, and the SDK rejects metadata: 'keep' on an AVIF or SVG base before upload rather than letting the server reject it.

auto_orient rotates per the EXIF orientation flag — worth pairing with metadata: 'strip', since stripping EXIF otherwise discards the orientation that some viewers rely on. Honored on the raster routes; SVG honors only metadata. auto_orient on an SVG format change is rejected before upload (SVG is vector — it cannot be auto-oriented).

await client
.file('photo.jpg')
.output(undefined, { metadata: 'keep', auto_orient: true })
.run({ maxWait: '2m' });

Colour profile and chroma

color_profile handles the embedded ICC profile: keep, srgb (convert), or strip. Availability depends on the route and value.

chroma_subsampling takes 420 (smallest), 422 or 444 (highest fidelity), and is honored on same-format JPEG only.

await client
.file('photo.jpg')
.output(undefined, { color_profile: 'srgb', chroma_subsampling: '444' })
.run({ maxWait: '2m' });

All options

OptionTypeHonored on
quality1100Same-format avif/jpeg/png/webp/gif/tiff, and lossy format changes.
encoding_modequality | target_sizeSame-format avif/jpeg/webp.
target_size_bytesnumber (≥ 1024)With encoding_mode: 'target_size'.
chroma_subsampling420 | 422 | 444Same-format jpeg.
width / heightnumberRaster routes. 1–16384; width × height ≤ 16MP.
fitmax | crop | scaleWhen width or height is set.
backgroundhex stringFormat change to jpeg — fills transparency.
progressivebooleanSame-format jpeg.
optimization_levelnumberSame-format png (lossless effort).
avif_speednumberSame-format avif (encode speed).
metadatastrip | keepSame-format. keep not offered on avif/svg. Planned on format change.
color_profilekeep | srgb | stripRoute- and value-dependent.
auto_orientbooleanRaster routes. Not honored on svg.
losslessbooleanSame-format jpeg/webp.

Passing a format in the options bag is rejected — the first argument owns it.

See also

  • Compress — presets and the simpler quality-only path.
  • Convert — format changes.
  • Watermark — stamping an overlay or a text label.