Matting: Basic
Trimap-guided FBA matting for accurate, feathered edges around hair, fur, and motion blur that a hard mask can't capture.
Source must be RGB JPEG. Trimap must be grayscale JPEG of the exact same dimensions. Any size mismatch misaligns the labels and produces bad results.
Use PNG or WebP for the output key when
output_type is "rgba" to preserve the alpha channel. Only use a JPEG output key when output_type is "mask".What is a trimap?
A trimap is a grayscale guide image the same size as your source photo. It pre-sorts every pixel into one of three zones:
White (255)
Definitely foreground. Kept, fully opaque.
Black (0)
Definitely background. Removed, fully transparent.
Gray (~128)
Unknown boundary. The model computes exact partial transparency here. Keep this band tight for best results.
Step 1 Upload source
| Endpoint | /v3/file-ops/upload/ |
| Content-Type | multipart/form-data |
| Requirement | RGB JPEG |
Step 2 Upload trimap
| Endpoint | /v3/file-ops/upload/ |
| Content-Type | multipart/form-data |
| Requirement | Grayscale JPEG, same size |
Step 3 Process
| Endpoint | /v3/tools/ai/matting/process/ |
| Content-Type | application/json |
| Returns | output_key |
import requests
API_KEY = "YOUR_API_KEY"
API_BASE = "https://api.backgroundcut.co"
HEADERS = {"Authorization": f"Token {API_KEY}"}
# Step 1 — Upload the source image (must be RGB JPEG)
with open("photo.jpg", "rb") as f:
requests.post(
f"{API_BASE}/v3/file-ops/upload/",
headers=HEADERS,
files={"file": f},
data={"key": "my-project/photo.jpg"},
timeout=60,
).raise_for_status()
# Step 2 — Upload the trimap (must be grayscale JPEG, same dimensions as photo.jpg)
# White (255) = definite foreground, Black (0) = definite background, Gray (~128) = unknown boundary
with open("trimap.jpg", "rb") as f:
requests.post(
f"{API_BASE}/v3/file-ops/upload/",
headers=HEADERS,
files={"file": f},
data={"key": "my-project/trimap.jpg"},
timeout=60,
).raise_for_status()
print("Uploaded source and trimap")
# Step 3 — Run matting
resp = requests.post(
f"{API_BASE}/v3/tools/ai/matting/process/",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"input_key": "my-project/photo.jpg",
"trimap_key": "my-project/trimap.jpg",
"output_key": "my-project/result.png", # PNG preserves transparency
"output_type": "rgba",
"output_compression": 95,
},
timeout=60,
)
resp.raise_for_status()
result = resp.json()
print("Matted:", result["output_key"])
# Step 4 — Mint a public URL to download the result
pub = requests.post(
f"{API_BASE}/v3/file-ops/get-public-url/",
headers={**HEADERS, "Content-Type": "application/json"},
json={"key": result["output_key"]},
timeout=10,
)
pub.raise_for_status()
print("Download URL:", pub.json()["url"])Matting Request Body
| Field | Type | Default | Description |
|---|---|---|---|
input_key | string | required | Key of the source RGB JPEG in your space. |
trimap_key | string | required | Key of the grayscale JPEG trimap in your space. Must be the same width and height as the source. |
output_key | string | required | Destination key. Use PNG or WebP for rgba output; JPEG only for mask output. |
output_type | string | "rgba" | "rgba" returns the full-color cutout with transparent background. "mask" returns the single-channel grayscale alpha matte (white = foreground, black = background); requires a JPEG output key. |
output_compression | integer | 95 | Encoder quality for lossy formats (1–100). Ignored for PNG (always lossless). |
Response
{
"output_key": "my-project/result.png"
} Error Responses
| Status | Meaning |
|---|---|
400 | Bad request: non-JPEG source or trimap, size mismatch, wrong output key extension for chosen output_type, or missing required field |
401 | Missing or invalid Authorization header |
402 | Insufficient credits |
404 | File not found: input_key or trimap_key does not exist (expired, deleted, or wrong region) |
504 | Processing timed out (~30 s). Retry with a tighter trimap gray band. |
Tips
- Tight gray band = faster and cleaner results. Matting only does expensive per-pixel work inside the gray zone. Paint gray only over the uncertain boundary, not over large solid areas.
- Dimensions must match exactly. The trimap is a per-pixel overlay over the source. Even a 1-pixel size difference misaligns the labels and ruins the output.
- Use PNG for transparency. Set
output_keyto a.pngpath whenoutput_typeis"rgba". JPEG cannot store transparency. - Mask output needs JPEG. If you only want the grayscale alpha matte (e.g. to feed into a compositor), set
output_type: "mask"and use a.jpgoutput key. - Upload both files before calling process. There is no way to stream them in; both must already exist in your space when the matting call is made.