encodeWithinBytes
Encode an image to fit under a byte budget.
const out = await rastermill.encodeWithinBytes(input, {
format: "jpeg",
maxBytes: 500_000,
search: { maxSide: [2048, 1536, 1024], quality: [85, 70, 55] },
});
// => EncodedImage & { withinBudget, chosen: { maxSide?, quality?, compressionLevel? } }
It re-encodes across a search space and returns the first result at or under maxBytes. If nothing fits, it returns the smallest result it produced (so you always get usable bytes). withinBudget tells you whether the cap was met, and chosen reports which settings were used.
#Options
type EncodeWithinBytesOptions = EncodeOptions & {
maxBytes: number;
search?: {
maxSide?: readonly number[]; // dimensions to try, largest first
quality?: readonly number[]; // JPEG quality steps
compressionLevel?: readonly number[]; // PNG compression steps
};
};
The search iterates maxSide outermost, then the format-relevant axis: quality for JPEG, compressionLevel for PNG, and dimensions only for WebP. Sensible defaults are used for any axis you omit. All other EncodeOptions (e.g. resize.fit, autoOrient, signal) are forwarded to each attempt.
#JPEG vs PNG vs WebP
- JPEG: searches
maxSide × quality. Best for photos under a hard cap. - PNG: searches
maxSide × compressionLevel. Lossless, so shrinking dimensions does most of the work. - WebP: searches
maxSide. Photon's WebP encoder does not expose quality, so Rastermill does not expose a WebP quality option yet.
// Shrink a PNG under 256 KB, lossless.
const png = await rastermill.encodeWithinBytes(input, {
format: "png",
maxBytes: 256_000,
});
#Result
The return value is a normal encode result plus chosen:
type EncodedImageWithinBytes = EncodedImage & {
withinBudget: boolean;
chosen: { maxSide?: number; quality?: number; compressionLevel?: number };
};