Skip to main content
This guide covers the four ways Convertly’s image CDN can decide where and how to crop and how to feed it the metadata you already have from a CMS, design tool, or art director. It also covers the standalone analyse endpoint that emits focal points and palettes you can persist alongside every upload.
Side-by-side crop examples for gravity=auto, gravity=smart, gravity=face, and focal points live on Transforms → Resize, crop & fit. This page goes deeper on focal points, entropy crops, and the analyze API.

When to use which mode

When auto is not enough

On off-centre hero images, gravity=auto (default saliency) can miss the subject. gravity=smart runs a heavier content-aware pass that scores detail, saturation, and skin tone across the frame.
Center gravity crop vs smart gravity crop on an off-centre aerial photo

Off-centre hero — gravity=center (left) vs gravity=smart (right).

For the full gravity comparison grid (auto, smart, face, center), see Transforms → Resize, crop & fit.

Manual focal points (fp=x,y)

fp=x,y accepts a normalised coordinate where (0, 0) is the top-left of the source and (1, 1) is the bottom-right. Both percentages and decimals work:
Convertly takes a pre-resize extract whose aspect ratio matches the requested w/h, then resizes that extract down. The focal point lands at the centre of the crop window, clamped if the requested aspect would push the window past a source edge. This is the cheapest crop mode — it’s pure pixel math with no analysis pass — and it’s the only mode that’s deterministic across renditions. If you serve the same image at 1200×800, 600×400, and 300×200 with the same focal point, all three crops centre on the same physical pixel.
Wide hero image with a focal point marker on the subject

Source hero with suggested focal point from /api/images/analyze (purple marker).

Center crop vs focal point crop side by side

gravity=center (left) clips the subject. fp=x,y (right) keeps it centred.

Face-aware cropping (gravity=face)

gravity=face runs face detection on the source and uses the highest-confidence face’s centre as the crop focus. If multiple faces are detected, the box with the highest confidence wins - group shots tend to lock onto whoever the model is most confident about, which is usually the closest or most-foreground person. If no face is detected (most product shots, landscapes, screenshots), the request transparently falls through to gravity=smart, then to the saliency strategy. So gravity=face is always at least as good as gravity=auto - it just adds a face-aware step on top.
See gravity=face for a side-by-side crop example. Detection cost depends on source size and cache state. Like every other smart-crop mode, this cost is paid once per cache miss - once the output bytes are cached, subsequent requests serve the cached render.

Content-aware smart cropping (gravity=smart)

gravity=smart (or its alias crop=smart) runs the smartcrop algorithm on the source. smartcrop scores every candidate window for three signals — pixel-level detail, saturation, and skin-tone presence — then returns the rectangle with the highest aggregate score for the requested aspect ratio. It’s slower than the saliency strategy (gravity=auto) by ~50–100ms on a typical 1080p source, but it picks the right region noticeably more often on:
  • Hero shots where the subject is off-centre
  • Portraits with significant negative space
  • Product photography with the item in a corner
  • Editorial imagery where the visual weight is asymmetric
The pass runs once per cache miss. Once the resulting bytes are cached, every subsequent request serves the already-encoded image with no analysis cost — so a single popular hero pays the smart-crop cost once and serves it billions of times for free. See gravity=smart for a side-by-side comparison with gravity=center.

Entropy cropping (gravity=entropy)

gravity=entropy picks the region with the highest pixel entropy — detail density — without saliency or face cues. Use it when there is no obvious subject: product flat-lays, fabric swatches, maps, or texture photography where you want the busiest area in frame.
Entropy-based crop on a dense texture flat-lay

Texture source — gravity=entropy keeps the most detailed region in frame.

Combining focal points with the API

The recommended pattern at scale:
  1. On upload, call /api/images/analyze once. Convertly persists the result on the stored file as metadata.image_analysis.
  2. On render, either pass fp=x,y explicitly or omit fp — the CDN reads stored analysis automatically for fit=cover crops on Convertly Storage files.
  3. Art director override: update the stored value (or pass fp=x,y on the URL). URLs stay deterministic.
This keeps the hot path zero-cost while letting you serve smart-cropped renditions to every device.

CDN focal discovery

Append focal=json after your resize params. The CDN resolves focal in priority order: explicit fp=x,y → stored image_analysis → inline face detection → smart-crop → centre.
Example response:
source is one of manual, metadata, face, smart-crop, or center. When cached is true, the value came from a prior /api/images/analyze run on the same file. fp=auto is the lazy mode when you have not analyzed yet:
The CDN runs face detection, then smart-crop for the requested aspect, and crops around the result. Cost is paid once per cache miss, same as gravity=smart.
focal=json returns focal metadata only — not palette or face boxes. Use POST /api/images/analyze for full analysis at upload time.

The analyze endpoint

POST /api/images/analyze returns the focal point smartcrop would pick, the suggested crop window in pixel coordinates, and a full colour palette. Use it once per upload, persist the result, and reuse it forever.

API Reference

OpenAPI spec and interactive playground for POST /api/images/analyze.

Authenticate

Same auth as every other media-tools API: a regular API key (cvly_…) or a logged-in session cookie. CDN signing keys are not accepted on this endpoint — it’s a workspace-write path, not a public CDN one.

Two request shapes

If the image is already in Convertly Storage, send a JSON body with the file’s id. No upload needed.

Fresh upload

If the image isn’t stored yet (onboarding, one-off analysis, “what colour is this?” calls), use multipart:
Multipart uploads are capped at 25 MB.

What analyze returns visually

Analyze runs face detection and palette extraction on the source once. Persist the JSON next to the file — every CDN render with fp=x,y stays deterministic and free of per-request analysis.
Face analysis boxes beside a face-aware crop result

Before: face analysis boxes. After: face-aware crop centered on the detected group.

Hero image with Original palette and Dominance palette swatch rows

Original and dominance palette swatches — two labelled rows below the image.

Colour palette extraction

Convertly supports two palette workflows:

CDN palette

Append palette=json or palette=css to any CDN URL after your resize, crop, and adjustment params. The CDN runs the full image pipeline, rasterises to PNG internally, extracts colours, and returns JSON or CSS instead of an image.
Landscape crop with Original palette and Dominance palette swatch rows below the image

CDN ?w=640&h=320&fit=crop&palette=json — Original palette (named swatches) and Dominance palette (population-sorted).

palette=json returns average_luminance, colors, dominant_colors, and dominant. palette=css emits .{prefix}-fg-N / .{prefix}-bg-N rules plus white/black exception classes. Each preview shows two swatch rows:
  1. Original palette — named swatches (vibrant, muted, light/dark variants).
  2. Dominance palette — the same colours sorted by pixel population (strongest first).
Palette extraction runs after transforms, so a warmed or cropped render produces different swatches than the stored original. Combine with sat, hue, crop, bgRemove, etc.
Warm-filtered landscape with palette swatch rows below

After ?sat=35&hue=18&con=92 — dominance swatches shift with the render.

Not combinable with format=svg&vectorize=gradient output — request palette on a raster format (webp, png) instead.

Analyze API (persist at upload)

Call POST /api/images/analyze once per upload, persist the JSON, and theme your UI from the swatches without a per-page CDN palette request. Each swatch includes: The doc preview shows two rows below the image:
  1. Original palettevibrant, muted, and light/dark variants (Material Design / node-vibrant categories).
  2. Dominance palette — the same swatches sorted by pixel weight so the strongest colours read left-to-right.

Palettes follow your transforms

For CDN palette, pass the same transform params on the URL — the swatches reflect the rendered output:
For analyze, the endpoint runs on the bytes you send — usually the stored original. If you want palette data that matches a styled render without CDN palette, fetch that render first, then POST those bytes:
Landscape with warm filter and Original and Dominance palette swatches below

Analyze on a warmed CDN render — Original and Dominance palette rows below the image.

SVG and analyse

Stored SVG files are accepted (image/svg+xml passes the image/* check). Internally the file is rasterised before quantisation, so palette extraction works on illustrated SVGs and icons. Smart crop and face detection on pure logo SVGs are usually low-confidence — expect focal.suggested.source: "center" for flat artwork.

Response

Field notes:
  • focal.suggested.{x, y} is normalised to [0, 1]. Paste straight into ?fp=x,y.
  • focal.suggested.confidence is in [0, 1]. Values under ~0.3 mean the algorithm couldn’t find a strong subject; treat them as “centre crop is probably fine.”
  • focal.suggested.source tells you which backend produced the focal point:
    • face — a face was detected; the focal point is the centre of the highest-confidence face box. Highly trustworthy.
    • smart-crop — no face found; smartcrop’s content-aware pick was used.
    • center — both passes failed (very small image, single-colour, or unsupported format); the centre is the safe fallback.
  • focal.crop is the suggested square crop window in source pixel coordinates. Useful if you want to physically store a thumbnail rather than render one on demand.
  • faces is the full list of detected face boxes, sorted by score descending. Each box is in source-image pixel coordinates with a confidence score. Empty array = no faces detected (a successful run); the field is present even when gravity=face would fall through to smart crop.
  • palette.dominant is whichever named swatch has the highest pixel population. Renders nicely as the card-background colour in product UIs.
  • palette.*.bodyTextOnColor is a WCAG-style “white or black for body text?” hint.

Quota

One /api/images/analyze call = 1 media operation against your plan’s monthly quota. All plans include the endpoint. See Limits for media API request allowances.

Platform fit

Convertly targets teams that want one platform for storage, conversion, compression, CDN delivery, and optional Forma AI. The tables below summarize what the Image CDN supports today.

Cropping, focal points, and analysis

Format, delivery, and platform

AI, privacy, and SVG

Metering (high level)

Convertly keeps transforms URL-first so storage, CDN delivery, and optimization can live in the same workflow.

Where Convertly fits best

  • Strong fit: Product teams that want resize, crop, format auto, watermarks, palette extraction, and ML background removal from flat transform URLs — plus origin-backed delivery without re-uploading every asset.
  • Evaluate carefully: Deep proprietary DAM workflows or apps that depend on a single-vendor upload widget and folder UI — Convertly offers folders and dashboard tools with a different model; plan a hybrid origin period if needed.
Use fp=x,y when you already know the subject position, or call /api/images/analyze when you want Convertly to suggest focal points and face boxes automatically.