Skip to main content
Version: 0.12

Background Removal: Foreground Cutout

Atelico removes the background from an image entirely on-device, producing an RGBA PNG with a transparent background — useful for turning photos or generated art into game-ready sprites and cutouts. No external API is involved.

model valueModelParamsLicenseBest for
isnetIS-Net (general)44MApache 2.0Photographic / general content (default)
isnet-animeIS-Net (anime)44MApache 2.0Stylized / anime artwork
birefnetBiRefNet (Swin-L)221MMITHighest quality, slower

Prefix with the backend as usual: in-memory::isnet. Unknown ids return a clear error listing the supported models.

The flow: a base64-encoded source image goes in, a base64-encoded RGBA PNG (with the background made transparent) comes out. Like image generation, every binding exposes a non-blocking async variant (*_async) since segmentation takes a moment on larger models.

Request fields

The request deserializes into a BackgroundRemovalRequest:

FieldTypeDefaultDescription
modelstringrequiredModel id, e.g. in-memory::isnet
imagestringrequiredSource image as base64-encoded PNG or JPEG
outputobjectsee belowWhat to return (RGBA image and/or mask)
refinementobjectsee belowPost-processing options for the alpha mask

output controls which artifacts come back:

output fieldTypeDefaultDescription
rgba_imagebooltrueReturn the RGBA cutout with transparent background
maskboolfalseAlso return the alpha mask separately (grayscale PNG)

refinement tunes the mask edges:

refinement fieldTypeDefaultDescription
smooth_radiusu320Gaussian blur radius for mask smoothing (0 = off)
feather_widthu320Alpha feathering width in pixels (0 = sharp edges)
thresholdf320.0Binarize soft edges, 0.01.0 (0 = keep soft)
fill_holesbooltrueFill small holes inside the foreground mask
min_region_sizeu320Drop disconnected foreground blobs below this pixel count (0 = off)

Response

The response is a BackgroundRemovalResponse. The image field holds the RGBA cutout; mask is present only when output.mask was requested. Both are b64_json PNG payloads carrying their own pixel dimensions:

{
"id": "...",
"created": 1234567890,
"model": "isnet",
"image": {"b64_json": "iVBORw0KGgo...", "width": 1024, "height": 1024},
"mask": null,
"stats": {
"preprocess_ms": 4.1,
"inference_ms": 38.0,
"postprocess_ms": 6.2,
"total_ms": 48.3
}
}

image.b64_json is a PNG with an alpha channel — the background pixels are fully transparent.

note

The mask in a mask response is a grayscale PNG where white is foreground and black is background. Request it (set output.mask to true) when you want to composite the subject onto a new background yourself rather than using the pre-cut RGBA image.

SDK usage (in-process)

Rust SDK

use atelico_sdk::{Engine, BackgroundRemovalRequest};
use base64::Engine as _;

let engine = Engine::new()?;

let src_b64 = base64::engine::general_purpose::STANDARD
.encode(std::fs::read("subject.png")?);

let request = BackgroundRemovalRequest {
model: "in-memory::isnet".into(),
image: src_b64,
..Default::default()
};

// Blocking
let response = engine.images().remove_background_sync(request)?;
let cutout = response.image.expect("rgba_image requested by default");
let png = base64::engine::general_purpose::STANDARD.decode(&cutout.b64_json)?;
std::fs::write("subject_cutout.png", &png)?;

For a game loop, engine.images().remove_background_async(request) returns a [StreamHandle] you drive with poll() / next() / next_blocking().

Python

import base64, json
from atelico import Engine

engine = Engine()

src_b64 = base64.b64encode(open("subject.png", "rb").read()).decode()

resp = json.loads(engine.image_remove_background(json.dumps({
"model": "in-memory::isnet",
"image": src_b64,
})))
cutout = base64.b64decode(resp["image"]["b64_json"])
open("subject_cutout.png", "wb").write(cutout)

engine.image_remove_background_async(...) takes the same request JSON and returns a JsonResultStream you poll for the final response.

C / FFI

// Blocking background removal
const char* request =
"{\"model\":\"in-memory::isnet\",\"image\":\"iVBORw0KGgo...\"}";
const char* response_json = NULL;
int rc = atelico_image_remove_background(engine, request, &response_json);
// response_json: {"id":..,"created":..,"model":"isnet",
// "image":{"b64_json":"iVBORw0KGgo...","width":1024,"height":1024},
// "mask":null,"stats":{...}}
// base64-decode image.b64_json to recover the RGBA PNG bytes.

atelico_image_remove_background_async takes the same request JSON and returns a stream handle; drive it with the shared atelico_stream_poll / atelico_stream_destroy loop (see the C FFI getting started guide). The output pointer is owned by the FFI layer's thread-local return buffer — copy it before the next API call on the same thread.

Demo

demos/background-removal is a desktop app (also iOS-buildable) that lets you load an image, pick a model (IS-Net general, IS-Net anime, or BiRefNet) and input resolution, and preview the transparent cutout. It is the recommended starting point before wiring foreground extraction into an asset pipeline.

See also