Skip to content

Image Processing

Picora can resize, crop, and reformat any image on the fly by appending query parameters to its URL. No uploads, no batch jobs — just edit the URL and the image is regenerated through image-serve and cached at the CDN edge for next time.

https://media.picora.me/abc123.jpg
?w=800
&h=600
&fit=cover
&fmt=webp
&q=85

The URL above asks for the image scaled to fill an 800×600 box (cropping if needed), encoded as WebP at quality 85.

Supported parameters

ParameterMeaningRangeDefault
wWidth in pixels1–4096original
hHeight in pixels1–4096original
fitScaling strategycover / contain / fill / inside / outsideinside
fmtOutput formatwebp / jpeg / png / aviforiginal
qQuality (jpeg / webp / avif)1–10085
wmWatermark template id (pro_plus only)nanoid(21)none

Anything else — for instance ?rotate=90, ?filter=blur, or ?text=hi — is rejected with 400 INVALID_IMAGE_PARAMS. This is intentional: the strict whitelist keeps the CDN cache key space bounded and prevents abuse vectors like SVG filter injection or text-overlay bombing.

Caching

A processed result is stored under variants/{imageId}/{paramsHash}.{ext} in object storage and cached at the CDN edge with Cache-Control: public, max-age=31536000. The cache key is a SHA-256 of the canonicalized parameter set, so callers passing the same parameters in any order share a cache hit.

Hit rate goal in production: ≥ 95 % measured over 24 hours.

Live preview

When you tweak parameters in the picora-center UI builder, the SDK appends ?preview=1 to the test URL. The server still processes the image but does not persist the result to storage and returns Cache-Control: no-store. This avoids polluting the cache with hundreds of throwaway combinations while you scrub a slider. Click “Copy URL” — the copied value never carries preview=1, so the first real visit triggers a normal cache write.

?preview=1 is rate-limited to 60 req/min per user.

Cross-platform consistency

The same URL produces visually identical output on picora.me (Cloudflare R2) and picora.cn (Aliyun OSS). The contract is “consistency tolerance < 5 % pixel diff” measured over the bundled validation set — Aliyun’s ?x-oss-process=image/resize produces slightly different aliasing than R2 + WebAssembly resize, but no consumer-perceptible difference.

If you need pixel-perfect determinism, generate the variant once on a single platform and serve the resulting variants/... key directly.

Errors

CodeWhen
INVALID_IMAGE_PARAMSA parameter is out of range, mistyped, or unknown
IMAGE_NOT_FOUNDThe image was deleted or never existed
IMAGE_PROCESS_FAILEDInternal error during resize / encode (retry once before giving up)

Errors from media.picora.me return a small placeholder PNG rather than JSON, so a <img src> tag renders gracefully even when the request fails.