Overview

Focal points, as a service.

A small Go HTTP service that finds the main visual subject in an image. It runs U²-Net with ONNX Runtime and returns the weighted centroid of the strongest salient region as normalized X/Y coordinates. It never crops, stores, or modifies the submitted image.

290–390 ms per imageJPEG · PNG · WebPCPU-only
Integration

Storage preview

Appwrite Storage accepts gravity=auto on the preview endpoint. When both width and height are set, autogravity finds the main subject and crops around its focal point instead of the geometric centre.

Golden retriever sitting on grass in a park
Original
400 by 400 preview cropped with gravity center
gravity=centerGeometric centre — subject cut off
400 by 400 preview cropped with gravity auto
gravity=autoFocal point — subject kept in frame
GET/v1/storage/buckets/{bucketId}/files/{fileId}/preview

Pass width, height, and gravity=auto to crop around the detected focal point.

Example
?width=400&height=400&gravity=auto
Start

Install

Fastest path is Docker. The image downloads the verified U²-Net model and the CPU-only ONNX Runtime library during the build.

Docker
$ docker run --rm -p 8080:8080 ghcr.io/appwrite/autogravity
$ docker build -t autogravity .
$ docker run --rm -p 8080:8080 autogravity

Or build from source with Go 1.25 or newer. make model downloads and verifies the ONNX model.

Source
$ make model
$ make build
$ ./autogravity
Start

Configuration

VariableDefaultPurpose
ADDR:8080HTTP listen address
MODEL_PATHmodels/u2net.onnxU²-Net model path
ONNXRUNTIME_LIBrequiredFull ONNX Runtime shared-library path
Reference

API

Send a JPEG, PNG, or WebP image as a multipart image field, or as the raw request body.

POST/analyze

Returns the strongest salient region's weighted focal point as normalized coordinates.

Request
curl -sS -X POST \
  http://localhost:8080/analyze \
  -F 'image=@photo.jpg'
Response
{
  "gravity": {
    "x": 0.68,
    "y": 0.37
  },
  "confidence": 0.91
}

Coordinates are in [0.0, 1.0], measured from the oriented image's top-left corner. EXIF orientation is applied before analysis. Images are fitted within the model's 320×320 input using neutral padding, without stretching or cropping. Confidence is the peak activation in the model's fused saliency map.

GET/healthz

Returns 503 until the model is loaded, then 200 with {"status":"ok"}.

Reference

Limits

Requests are limited to 10 MiB and decoded images to 20 megapixels. Separate upload and analysis admission limits bound buffered-body and decoded-image memory without allowing slow uploads to reserve inference capacity. The model is loaded once at startup and its shared inference session is reused across requests.

Reference

Performance

InputDimensionsTime per image
Landscape JPEG1280 × 720391.4 ms
Portrait PNG720 × 1080291.3 ms

Apple M3 Pro, CPU-only ONNX Runtime 1.23.2, Go 1.25.14. Median of five sequential benchmark samples. Performance varies with hardware and input images.