Skip to main content
This page is a hands-on guide to localized editing (inpainting) with gpt-image-2 via POST /v1/images/edits, by uploading an image + mask + prompt. For full parameter reference and the interactive Playground, see Image Edit API Reference.

Core Principle: the Alpha Channel Defines the Edit Region

A localized edit request consists of three parts:
The mask marks editable regions through the PNG alpha (transparency) channel:
The most common mistake: what determines the edit region is the alpha channel, not the black or white pixels you see.
A PNG that “looks black and white” but has no alpha channel will fail with invalid_image_file.

A Visual Example

Suppose the original image is 1024×1024:
With a prompt like:

The Mask Is Not a Hard Crop

GPT Image masks are not absolute pixel-level constraints like Photoshop selections. Officially, mask editing remains prompt-guided editing: the model uses the mask as a reference but does not guarantee strict adherence to every pixel boundary. You may therefore see:
  • Slight shadow changes outside the mask
  • Object edges extending beyond the mask
  • Coordinated lighting and reflection changes
  • Minor background repainting
  • Transition effects near mask boundaries
This is good for natural blending, but not suitable when pixel-perfect preservation is required (see “Strictly Preserving Content Outside the Mask” below).

Improving Edit Stability

Don’t just write “change it to a red shirt”. Write instead:
Practical tips:
  1. Make the mask slightly larger than the target object’s edges
  2. Don’t just cover the object’s center — include edges, shadows, and reflections
  3. Explicitly state what must remain unchanged
  4. If the edit region is too small, enlarge the mask
  5. When absolute preservation is required, do a final pixel composite yourself (see below)

To Mask or Not to Mask? Trade-offs vs Prompt-Only Editing

A common question: modern AI can already “edit exactly what you point at” with plain language — why bother making a mask? It’s true that gpt-image-2 without a mask, given just “replace the cup on the left side of the table with flowers”, usually edits the right spot — instruction following is strong, and for casual edits a prompt alone is enough. But a mask solves the cases where language is ambiguous, or unambiguous but still not reliable enough: Research points the same way: mask-free (purely text-driven) editing struggles with precise spatial control — prompt-to-prompt style methods, for instance, cannot spatially move an object across the frame, and when the implicit edit region is off, you get “the part that should change didn’t, and the part that shouldn’t did.” Mask-based editing trades a little convenience for explicit spatial precision.
In one sentence: masks aren’t obsolete tech — they’ve shifted from “required” to “a precision-control tool”. Casual chat-style edits → prompt alone; production workloads that must be reproducible, controllable, and boundary-strict → use a mask. Also remember: prompt-only editing with gpt-image-2 is essentially whole-image regeneration, so unspecified regions may change too — which is exactly why mask + pixel compositing exists.

File Requirements at a Glance

Role assignment when editing with multiple images:
“Exactly matching dimensions” sounds tedious, but you never align sizes by hand — masks are derived from the original image (by erasing / brushing / segmenting on a copy of it), so matching dimensions come for free. See Where Do Masks Come From below.

Python Example

Do not pass input_fidelity="high"gpt-image-2 always processes input images at high fidelity by default. The API does not allow adjusting this parameter; passing it returns a 400 error. Simply omit it.

cURL Example

The image edit endpoint requires multipart/form-data — you cannot submit the image and mask as plain JSON fields:
Even with a single image, use the image[] field name as in the official examples.
When using -F, do not manually set -H "Content-Type: multipart/form-data". curl needs to generate the boundary automatically; setting the header manually drops the boundary and the server cannot parse the files.

Node.js Example

Where Do Masks Come From? Five Common Methods

People often find masks intimidating — “it has to match the original image pixel for pixel”. The key realization: you almost never draw a mask from scratch; you derive it from the original image. Whether via code, a photo editor, or a web canvas, the flow is always “open the original → mark regions on it → export”, so matching dimensions are automatic.

Method 1: Generate a Transparent Mask Programmatically

Set a rectangular region to transparent (editable):
  • (255, 255, 255, 255) = opaque, preserved region
  • (0, 0, 0, 0) = transparent, editable region

Method 2: Manual Erasing in a Photo Editor

Any editor that supports transparent PNGs (Photoshop, GIMP, Krita, Photopea, etc.) can produce a mask — it boils down to one action: erase the region you want edited into transparency. In Photoshop:
  1. Open a copy of the original image (working on the original itself guarantees matching dimensions)
  2. If the layer is a locked “Background”, double-click to convert it to a normal layer (background layers don’t support transparency)
  3. Select the region to modify with the Lasso / Quick Selection / Object Selection tool
  4. Press Delete — the selection becomes the transparent checkerboard
  5. “Export As PNG” (with transparency enabled) — the result is a valid alpha mask
Same idea in GIMP: Layer → Transparency → Add Alpha Channel, select, Delete, export as PNG.
Shapes are in no way limited to rectangles — trace an object with the lasso or one-click a subject with smart selection, and the erased transparent region takes any irregular shape. Expand the selection a few pixels beyond the object’s outline (Photoshop: Select → Modify → Expand) so shadows and edges are covered too.

Method 3: Web Brush Canvas

The “brush over what you want changed” interaction in AI photo apps is just an alpha mask generated live in the browser, built around a single Canvas API property. See How Brush-Style Editing Works below.

Method 4: One-Click Masks via AI Segmentation

If even brushing feels like work, let a segmentation model do it. Meta’s open-source SAM (Segment Anything Model) family is the mainstream option:
  • Click to mask: click an object once and the model returns its pixel-accurate outline (down to hair-strand edges)
  • Text to mask: SAM 3, open-sourced in November 2025, accepts concept-level text prompts like “all yellow taxis” or “players wearing red jerseys” and returns masks for every matching instance (model and code at github.com/facebookresearch, overview at ai.meta.com)
  • Subject / background split: open-source tools like rembg separate subject from background in one command — the background region can directly serve as a “change only the background” mask
Segmentation output is usually a black-and-white bitmap; convert it with “Method 5” below. The Stable Diffusion community’s Inpaint Anything extension and ComfyUI’s Mask Editor are mature implementations of exactly this pipeline — “SAM segmentation + brush touch-up → mask → inpaint” — and worth borrowing from.

Method 5: Convert a Black-and-White Mask to an Alpha Mask

If you already have a mask where “black = edit, white = keep”:

Validate the Mask Before Uploading

Many invalid_image_file errors happen because a file has a .png extension but only RGB channels and no alpha. Run this before uploading:

Mask Shapes and How Brush-Style Editing Works

Masks Can Be Any Irregular Shape

A mask is fundamentally a per-pixel bitmap, not a geometric shape — every pixel carries its own alpha value. So:
  • Rectangles and circles are just the simplest examples
  • A person-shaped silhouette, hair-strand edges, a freehand scribble, or multiple disconnected patches are all valid
  • In practice most masks are irregular: they follow the target object’s outline, slightly expanded
The only “shape advice” is about results, not rules: the transparent region should fully cover the object plus its edges, shadows, and reflections. Err on the generous side so the model has room to blend naturally.

How Brush-Style Editing Is Implemented

The “brush where you want changes” interaction in photo apps is surprisingly simple on the front end: two stacked layers, with the brush “erasing” the top one into transparency.
The core is one line — set the canvas compositing mode to destination-out (new strokes “carve out” existing pixels):
Engineering details that matter:
  1. Coordinate conversion: the canvas is usually scaled down by CSS on the page; convert stroke coordinates back by naturalWidth / clientWidth, or the mask will be misaligned
  2. Undo: snapshot with ctx.getImageData() before each stroke and restore with putImageData()
  3. Mask dilation: users tend to brush only the object’s center — programmatically expand the mask a few pixels before submitting (the “Expand Mask” button in professional tools); on the Python side use PIL.ImageFilter.MaxFilter or OpenCV’s cv2.dilate
  4. Semi-transparent preview: draw the user-facing highlight (e.g. translucent red) on a separate preview layer, keeping the exported mask layer strictly binary opaque/transparent

Going Further: Click or Text to Mask

One step beyond brushing is replacing “human strokes” with “model inference”:
This is exactly how Inpaint Anything and ComfyUI’s Mask Editor work: segmentation handles precision, the brush handles corrections — auto-generate an accurate mask first, then fine-tune with add/trim brush strokes. For your own product, deploying SAM as a backend service while keeping a brush canvas as the fallback is currently the best-UX combination.

Multiple Reference Images + Mask

A typical scenario: outfit swap (first image is the person, followed by style / fabric references; the mask marks the clothing region):
With multiple images, the prompt must clearly describe each image’s role (first = subject, second = style reference, third = fabric reference); otherwise the model may confuse them.

Strictly Preserving Content Outside the Mask (Pixel-Level Post-Processing)

Since the model may slightly alter content outside the mask, for pixel-accuracy scenarios (product shots, ID layouts, fixed UI screenshots), composite the region outside the mask back from the original after generation:
Result: the AI edit inside the mask, the original image outside it, with a lightly feathered boundary.

Common Errors

Common causes:
  • The mask is not a valid PNG, or the file is corrupted
  • The extension says PNG but the actual encoding is not PNG
  • Abnormal image mode (CMYK, palette mode, missing alpha)
  • Wrong MIME type on upload
  • The file stream was already consumed or closed before the request
Re-encoding fixes most cases:
Even a 1-pixel difference fails. Fix:
RGB / L / P modes are not enough — the mask must be RGBA. Use “Method 2” above to convert.
The mask itself can contain transparency (that is how you mark the edit region), but gpt-image-2 does not support transparent output backgrounds:
Use "opaque" or "auto" for background; passing "transparent" returns an error.
GPT Image models always return Base64 data; response_format only applies to legacy DALL·E 2 behavior. Read the result via:
Usually caused by manually setting the Content-Type header (losing the boundary), or a middle layer parsing the multipart request into JSON before forwarding. Let your HTTP client generate the multipart headers automatically.

Size Parameters

gpt-image-2 supports flexible dimensions, subject to all of the following:
Common sizes: 1024x1024, 1536x1024, 1024x1536, 2048x2048, 2048x1152, 3840x2160, 2160x3840, auto. Square images usually generate faster.

Production Request Template

Image Edit API Reference

Full parameter reference and interactive Playground

GPT-Image-2 Overview

Model capabilities, pricing, and version notes
Official references (copy into your browser):
  • Model page: developers.openai.com/api/docs/models/gpt-image-2
  • Image edit API reference: developers.openai.com/api/reference/python/resources/images/methods/edit/
  • Image generation guide: developers.openai.com/api/docs/guides/image-generation