> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bfl.ml/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Editing

> How image editing works in FLUX 3 Image: send your images, write the change as an instruction, refer to references by position, and add box rows when a change must go in an exact region.

export const EditingShowcase = () => {
  const [activeId, setActiveId] = useState("starting");
  const categories = [{
    id: "starting",
    title: "Input image",
    description: "The image every edit starts from.",
    prompt: "The input image. Each tab sends this image with one instruction to FLUX 3 Image.",
    image: "https://cdn.sanity.io/images/2gpum2i6/production/03cb44b883709a79500c46d8db8e0d0fc932413d-1440x1024.png"
  }, {
    id: "character",
    title: "Change the character",
    description: "Replace or transform people and creatures in your scene.",
    prompt: "Replace the white bird with a silver fox sitting in the same outdoor puddle. The fox has thick silver-grey fur, a bushy tail and natural amber eyes. Keep the puddle, grass, butterfly, low camera viewpoint and warm golden light unchanged. The fox occupies the bird's position, with a coherent reflection and paws touching the water.",
    image: "/images/flux3-image/regen/overview-character.webp"
  }, {
    id: "composition",
    title: "Adjust the composition",
    description: "Reframe and restructure your image.",
    prompt: "Use the white parakeet bathing in the puddle in the reference image as the subject. Zoom out to a wider view of the same outdoor scene, showing more of the grassy banks, shallow puddle and woodland beyond. Preserve the bird's appearance and bathing pose, the hovering butterfly, water splashes, golden lighting and low viewpoint. The bird occupies less of the wider frame while keeping the same scale relative to the puddle.",
    image: "/images/flux3-image/regen/overview-composition.webp"
  }, {
    id: "action",
    title: "Alter the action",
    description: "Change what the subject is doing.",
    prompt: "Use the white parakeet bathing in the puddle in the reference image as the subject. Change the bird's action so it stands upright in the same puddle with both wings fully spread, throwing a small arc of water droplets from each wing. Keep its white plumage, the long tail, grassy banks, butterfly, warm golden light and low camera viewpoint. Its feet touch the shallow water with a coherent reflection.",
    image: "/images/flux3-image/regen/overview-action.webp"
  }, {
    id: "setting",
    title: "Swap the setting",
    description: "Transform the environment, as much or as little as you like.",
    prompt: "Use the white parakeet bathing in the puddle in the reference image as the subject. Change only the environment into a cavernous abandoned factory with rusted machinery and soft light shafts through broken skylights. Keep the bird's appearance, bathing pose, butterfly, shallow puddle and camera framing. The puddle now lies on the concrete factory floor; industrial walls and machinery replace all surrounding grass and trees.",
    image: "/images/flux3-image/regen/overview-setting.webp"
  }];
  const active = categories.find(c => c.id === activeId) || categories[0];
  return <div className="not-prose" style={{
    borderRadius: "1rem",
    overflow: "hidden",
    border: "1px solid rgba(255,255,255,0.1)",
    background: "#111210"
  }}>
      <div style={{
    position: "relative",
    aspectRatio: "4/3",
    overflow: "hidden"
  }}>
        <img src={active.image} alt={active.id === "starting" ? "Input image: a white bird bathing in a puddle at golden hour" : "FLUX 3 Image edit: " + active.title} style={{
    display: "block",
    width: "100%",
    height: "100%",
    objectFit: "cover"
  }} />
      </div>
      <p style={{
    margin: 0,
    padding: "1rem 1.5rem",
    minHeight: "7.5rem",
    color: "rgba(255,255,255,0.88)",
    fontFamily: "monospace",
    fontSize: "0.82rem",
    lineHeight: 1.65
  }}>
        {active.prompt}
      </p>
      <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(5, 1fr)",
    gap: "0"
  }}>
        {categories.map(cat => {
    const isActive = cat.id === activeId;
    return <button key={cat.id} onClick={() => setActiveId(cat.id)} style={{
      display: "block",
      width: "100%",
      padding: "1rem 1.25rem",
      border: "none",
      borderRight: "1px solid rgba(255,255,255,0.08)",
      background: isActive ? "rgba(255,255,255,0.06)" : "transparent",
      textAlign: "left",
      cursor: "pointer",
      color: "#f5f5f5",
      borderTop: isActive ? "2px solid rgba(255,255,255,0.5)" : "2px solid transparent"
    }}>
              <div style={{
      fontWeight: 600,
      fontSize: "0.9rem",
      color: isActive ? "#fff" : "rgba(255,255,255,0.6)"
    }}>
                {cat.title}
              </div>
            </button>;
  })}
      </div>
    </div>;
};

export const MultiRefGrid = ({inputs = [], result = {}, prompt = ""}) => {
  const [hoveredInput, setHoveredInput] = useState(-1);
  const colors = [{
    bg: "rgba(99,182,137,0.22)",
    border: "#63b689",
    text: "#63b689"
  }, {
    bg: "rgba(130,170,255,0.22)",
    border: "#82aaff",
    text: "#82aaff"
  }, {
    bg: "rgba(255,180,107,0.22)",
    border: "#ffb46b",
    text: "#ffb46b"
  }, {
    bg: "rgba(199,140,230,0.22)",
    border: "#c78ce6",
    text: "#c78ce6"
  }, {
    bg: "rgba(255,130,130,0.22)",
    border: "#ff8282",
    text: "#ff8282"
  }, {
    bg: "rgba(130,220,220,0.22)",
    border: "#82dcdc",
    text: "#82dcdc"
  }, {
    bg: "rgba(220,200,120,0.22)",
    border: "#dcc878",
    text: "#dcc878"
  }, {
    bg: "rgba(200,160,180,0.22)",
    border: "#c8a0b4",
    text: "#c8a0b4"
  }];
  const renderPrompt = () => {
    if (!prompt) return null;
    const parts = [];
    let lastIndex = 0;
    const re = /\b(image\s+(\d))\b/gi;
    let m;
    while ((m = re.exec(prompt)) !== null) {
      if (m.index > lastIndex) parts.push({
        text: prompt.slice(lastIndex, m.index),
        idx: -1
      });
      parts.push({
        text: m[1],
        idx: parseInt(m[2], 10) - 1
      });
      lastIndex = m.index + m[0].length;
    }
    if (lastIndex < prompt.length) parts.push({
      text: prompt.slice(lastIndex),
      idx: -1
    });
    return parts.map((p, i) => {
      if (p.idx >= 0 && p.idx < colors.length) {
        const c = colors[p.idx];
        return <span key={i} style={{
          color: c.text,
          fontWeight: 700,
          padding: "1px 5px",
          borderRadius: "3px",
          background: hoveredInput === p.idx ? c.bg : "transparent",
          transition: "background 200ms"
        }}>
            {p.text}
          </span>;
      }
      return <span key={i}>{p.text}</span>;
    });
  };
  const getGridCols = () => {
    const n = inputs.length;
    if (n <= 3) return n;
    if (n === 4) return 2;
    if (n <= 6) return 3;
    return 4;
  };
  const gridCols = getGridCols();
  return <div className="not-prose" style={{
    borderRadius: "0.75rem",
    overflow: "hidden",
    border: "1px solid rgba(255,255,255,0.08)",
    background: "rgba(0,0,0,0.35)"
  }}>

      {}
      <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(" + gridCols + ", 1fr)",
    gap: "3px",
    padding: "3px",
    background: "rgba(0,0,0,0.3)"
  }}>
        {inputs.map((img, idx) => {
    const c = colors[idx % colors.length];
    const isHovered = hoveredInput === idx;
    return <div key={idx} onMouseEnter={() => setHoveredInput(idx)} onMouseLeave={() => setHoveredInput(-1)} style={{
      position: "relative",
      overflow: "hidden",
      cursor: "default",
      aspectRatio: "4/3",
      outline: isHovered ? "2px solid " + c.border : "2px solid transparent",
      outlineOffset: "-2px",
      transition: "outline-color 200ms ease",
      borderRadius: "4px"
    }}>
              <img src={img.src} alt={img.label || "Input " + (idx + 1)} style={{
      display: "block",
      width: "100%",
      height: "100%",
      objectFit: "cover",
      pointerEvents: "none"
    }} />
              <div style={{
      position: "absolute",
      top: "4px",
      left: "4px",
      width: "22px",
      height: "22px",
      borderRadius: "50%",
      background: c.border,
      color: "#000",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      fontSize: "0.65rem",
      fontWeight: 800,
      boxShadow: "0 1px 4px rgba(0,0,0,0.5)"
    }}>
                {idx + 1}
              </div>
            </div>;
  })}
      </div>

      {}
      <div style={{
    display: "flex",
    justifyContent: "center",
    padding: "4px 0",
    background: "rgba(0,0,0,0.3)"
  }}>
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
          <path d="M12 5v14M6 13l6 6 6-6" stroke="rgba(255,255,255,0.3)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </div>

      {}
      <div style={{
    position: "relative",
    padding: "0 3px 3px",
    background: "rgba(0,0,0,0.3)"
  }}>
        <img src={result.src} alt={result.label || "Result"} style={{
    display: "block",
    width: "100%",
    height: "auto",
    borderRadius: "4px",
    pointerEvents: "none"
  }} />
        <div style={{
    position: "absolute",
    top: "6px",
    right: "9px",
    padding: "3px 10px",
    borderRadius: "5px",
    background: "rgba(0,0,0,0.6)",
    backdropFilter: "blur(4px)",
    color: "#fff",
    fontSize: "0.65rem",
    fontWeight: 600
  }}>
          Result
        </div>
      </div>

      {}
      {prompt && <div style={{
    padding: "0.4rem 0.5rem 0.5rem"
  }}>
          <div style={{
    padding: "0.4rem 0.6rem",
    borderRadius: "6px",
    background: "rgba(255,255,255,0.04)",
    border: "1px solid rgba(255,255,255,0.08)",
    fontFamily: "monospace",
    fontSize: "0.68rem",
    lineHeight: 1.5,
    color: "rgba(255,255,255,0.7)"
  }}>
            <span style={{
    color: "rgba(255,255,255,0.35)",
    fontSize: "0.6rem",
    marginRight: "5px"
  }}>prompt:</span>
            {renderPrompt()}
          </div>
        </div>}
    </div>;
};

export const PromptDisplay = ({prompt}) => {
  const [copied, setCopied] = useState(false);
  const copy = () => {
    navigator.clipboard.writeText(prompt);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  return <div className="not-prose" style={{
    marginTop: "1rem"
  }}>
      <div style={{
    backgroundColor: "#1a1a1a",
    borderRadius: "1rem",
    padding: "1.25rem 1.5rem",
    display: "flex",
    flexDirection: "column",
    gap: "1rem"
  }}>
        <p style={{
    color: "#e5e5e5",
    fontSize: "1rem",
    lineHeight: 1.6,
    margin: 0,
    fontFamily: "inherit"
  }}>
          {prompt}
        </p>
        <div style={{
    display: "flex",
    justifyContent: "flex-end"
  }}>
          <button onClick={copy} style={{
    backgroundColor: copied ? "#3d8a5b" : "var(--aspen-evergreen, #486A58)",
    color: "#fff",
    border: "none",
    borderRadius: "0.375rem",
    padding: "0.25rem 0.6rem",
    fontSize: "0.7rem",
    fontWeight: 600,
    cursor: "pointer",
    transition: "background-color 0.2s"
  }}>
            {copied ? "Copied!" : "Copy prompt"}
          </button>
        </div>
      </div>
    </div>;
};

export const ImageExamples = ({examples = []}) => {
  const [copied, setCopied] = useState(null);
  const [expanded, setExpanded] = useState({});
  const [viewer, setViewer] = useState(null);
  const [actualSize, setActualSize] = useState(false);
  const openViewer = index => {
    setActualSize(false);
    setViewer(index);
  };
  const copyPrompt = async (prompt, index) => {
    try {
      await navigator.clipboard.writeText(prompt);
      setCopied(index);
      setTimeout(() => setCopied(null), 2000);
    } catch {
      setCopied(null);
    }
  };
  return <div className="not-prose flux3-image-examples" style={{
    "--example-columns": examples.length
  }}>
      <style>{`
        .flux3-image-examples {
          display: grid;
          grid-template-columns: repeat(var(--example-columns), minmax(0, 1fr));
          gap: 1rem;
          margin: 1.5rem 0;
        }
        .flux3-image-examples figure {
          display: flex;
          flex-direction: column;
          min-width: 0;
          margin: 0;
        }
        .flux3-image-examples .image-example-frame {
          display: flex;
          align-items: center;
          justify-content: center;
          aspect-ratio: 3 / 2;
          overflow: hidden;
          background: rgba(127, 127, 127, 0.08);
          border-radius: 0.75rem;
        }
        .flux3-image-examples .image-example-frame img {
          display: block;
          width: 100%;
          height: 100%;
          object-fit: contain;
          margin: 0;
          border-radius: 0;
        }
        .flux3-image-examples figcaption {
          margin-top: 0.75rem;
          font-size: 0.875rem;
        }
        .flux3-image-examples .image-example-prompt {
          display: flex;
          flex: 1;
          flex-direction: column;
          gap: 1rem;
          padding: 1.25rem;
          border-radius: 0.75rem;
          background: rgba(127, 127, 127, 0.08);
        }
        .flux3-image-examples .image-example-prompt p {
          margin: 0;
          line-height: 1.6;
        }
        .flux3-image-examples .image-example-prompt button {
          padding: 0.35rem 0.65rem;
          border-radius: 0.375rem;
          background: var(--aspen-evergreen, #486A58);
          color: white;
          font-size: 0.75rem;
          font-weight: 600;
          cursor: pointer;
        }
        .flux3-image-examples .image-example-frame button {
          display: block;
          width: 100%;
          height: 100%;
          padding: 0;
          border: 0;
          background: none;
          cursor: zoom-in;
        }
        .flux3-image-examples .image-example-prompt p.is-clamped {
          display: -webkit-box;
          -webkit-line-clamp: 4;
          -webkit-box-orient: vertical;
          overflow: hidden;
        }
        .flux3-image-examples .image-example-actions {
          display: flex;
          justify-content: flex-end;
          gap: 0.5rem;
          margin-top: auto;
        }
        .flux3-image-examples .image-example-actions .image-example-more {
          background: transparent;
          color: inherit;
          border: 1px solid rgba(128, 128, 128, 0.35);
        }
        .flux3-image-viewer {
          width: 100vw;
          height: 100vh;
          max-width: none;
          max-height: none;
          margin: 0;
          padding: 0;
          border: 0;
          overflow: auto;
          background: rgba(0, 0, 0, 0.95);
          cursor: zoom-out;
        }
        .flux3-image-viewer::backdrop {
          background: rgba(0, 0, 0, 0.6);
        }
        .flux3-image-viewer img {
          display: block;
          margin: auto;
          border-radius: 0;
        }
        .flux3-image-viewer.is-fit {
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 2rem;
        }
        .flux3-image-viewer.is-fit img {
          max-width: 100%;
          max-height: 100%;
          object-fit: contain;
        }
        .flux3-image-viewer .flux3-image-viewer__bar {
          position: fixed;
          top: 1rem;
          right: 1rem;
          display: flex;
          gap: 0.5rem;
        }
        .flux3-image-viewer .flux3-image-viewer__bar button {
          padding: 0.35rem 0.75rem;
          border-radius: 0.375rem;
          background: rgba(255, 255, 255, 0.15);
          color: white;
          font-size: 0.8rem;
          font-weight: 600;
          cursor: pointer;
        }
        @media (max-width: 640px) {
          .flux3-image-examples { grid-template-columns: minmax(0, 1fr); }
        }
      `}</style>
      {examples.map(({src, alt, label, prompt, zoom, focus = "50% 50%"}, index) => <figure key={`${src}-${index}`}>
          <div className="image-example-frame">
            <button type="button" onClick={() => openViewer(index)} aria-label={`View full size: ${alt}`}>
              <img src={src} alt={alt} loading="lazy" style={zoom ? {
    transform: `scale(${zoom})`,
    transformOrigin: focus
  } : undefined} />
            </button>
          </div>
          {prompt ? <figcaption className="image-example-prompt">
              <p className={expanded[index] ? undefined : "is-clamped"}>{prompt}</p>
              <div className="image-example-actions">
                {prompt.length > 240 ? <button type="button" className="image-example-more" aria-expanded={!!expanded[index]} onClick={() => setExpanded({
    ...expanded,
    [index]: !expanded[index]
  })}>
                    {expanded[index] ? "Show less" : "Full prompt"}
                  </button> : null}
                <button type="button" onClick={() => copyPrompt(prompt, index)} aria-live="polite">
                  {copied === index ? "Copied!" : "Copy prompt"}
                </button>
              </div>
            </figcaption> : label ? <figcaption>{label}</figcaption> : null}
        </figure>)}
      {viewer !== null ? <dialog className={actualSize ? "flux3-image-viewer" : "flux3-image-viewer is-fit"} aria-label={examples[viewer].alt} ref={node => {
    if (node && !node.open) node.showModal();
  }} onClose={() => setViewer(null)} onClick={() => setViewer(null)}>
          <img src={examples[viewer].full || examples[viewer].src} alt={examples[viewer].alt} style={{
    cursor: actualSize ? "zoom-out" : "zoom-in"
  }} onClick={event => {
    event.stopPropagation();
    setActualSize(!actualSize);
  }} />
          <div className="flux3-image-viewer__bar" onClick={event => event.stopPropagation()}>
            <button type="button" onClick={() => setActualSize(!actualSize)}>
              {actualSize ? "Fit to screen" : "Actual size"}
            </button>
            <button type="button" onClick={() => setViewer(null)}>Close</button>
          </div>
        </dialog> : null}
    </div>;
};

Send one or more images in `images` and write the change you want in `prompt`. Use the same endpoint as for image generation. There is no edit mode, mask, or strength setting: the prompt says what to do with the images, whether that is changing a detail, restyling, or combining them.

## How an edit request works

| Field | What to send |
| - | - |
| `images` | 1 to 10 reference images, as URLs or base64 strings. The first entry is “image 1”. |
| `prompt` | The change, written as an instruction. With several images, refer to each by position: “image 1”, “image 2”. |
| `aspect_ratio` | Leave it at `auto` (the default) and the output keeps the aspect ratio of image 1. |

This edit changes one bird in a flock:

<ImageExamples
  examples={[
{
src: "https://cdn.sanity.io/images/2gpum2i6/production/4792198dfeba9223bf3ecf020fed2942de7f0bd7-1800x1200.webp",
alt: "Source image: a flock of black bird silhouettes on a pale sky.",
label: "Source"
},
{
src: "https://cdn.sanity.io/images/2gpum2i6/production/6995df5d4ab590ca0b4eec142c27a643582a5f01-1248x832.webp",
alt: "The edited flock: one bird at the center is now pink, every other bird is still black.",
label: "FLUX 3 Image edit"
},
{
src: "https://cdn.sanity.io/images/2gpum2i6/production/6995df5d4ab590ca0b4eec142c27a643582a5f01-1248x832.webp",
alt: "Close-up of the center of the edited image, showing the single pink bird among black ones.",
label: "Center enlarged 4×",
zoom: 4,
focus: "51% 49%"
}
]}
/>

<PromptDisplay prompt="change the color of only one bird in the middle to #e01075" />

```json theme={null}
{
  "prompt": "change the color of only one bird in the middle to #e01075",
  "images": ["https://cdn.sanity.io/images/2gpum2i6/production/4792198dfeba9223bf3ecf020fed2942de7f0bd7-1800x1200.webp"]
}
```

The instruction specifies a target, a position, and a color. Check the result
when color accuracy or unchanged pixels matter. [Pixel preservation](/flux_3/flux3_image_layout#pixel-preservation)
shows measured examples.

## Combine several references

With more than one image, give each a role and refer to it by its position in `images`. Here, image 1 is the subject and image 2 is the style:

<MultiRefGrid
  inputs={[
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/ababcf5c9cf86074d71c92d6362ff63545d90661-1800x1201.webp", label: "Image 1: a weathered stone temple" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/dc642f5b01040c4afc46c1b4f8c4945152932683-1350x1800.webp", label: "Image 2: a watercolor of a figure pinning a crescent moon to a clothesline" },
]}
  result={{ src: "https://cdn.sanity.io/images/2gpum2i6/production/c1923cb51f693f1abee0c35fc41f9a0be6104e66-1248x832.webp", label: "FLUX 3 Image result: the temple in the palette and texture of image 2" }}
  prompt="Turn Image 1 in the Style of Image 2"
/>

`aspect_ratio: "auto"` follows the first reference, so the result is landscape like the temple. Put the image whose aspect ratio you want first, or set `aspect_ratio`. [Multi-reference editing](/guides/prompting_editing_multi_reference) covers roles, ordering, and larger compositions.

## When to use boxes

Start with a written instruction. Add [box rows](/flux_3/flux3_image_bounding_boxes#edit-an-image)
when several similar objects match the description, or when you need to
specify a position or size. Boxes can identify an element in a reference
and its intended position in the output.

## What an instruction can change

Each tab below sends the same input image with one instruction. The four edits are separate requests, not a chain.

<EditingShowcase />

## Guides in this section

<CardGroup cols={2}>
  <Card title="Single-reference editing" icon="pen-to-square" href="/guides/prompting_editing_single_reference">
    Write the instruction for one image, with a catalog of edit types.
  </Card>

  <Card title="Multi-reference editing" icon="images" href="/guides/prompting_editing_multi_reference">
    Combine up to 10 images: roles, ordering, and composites.
  </Card>

  <Card title="Edit with boxes" icon="vector-square" href="/flux_3/flux3_image_bounding_boxes#edit-an-image">
    Target exact regions with box rows: recolor, replace, move, or remove.
  </Card>

  <Card title="FLUX 3 Image Editing" icon="code" href="/flux_3/flux3_image_layout#edit-with-an-instruction">
    The API request for edits, with parameters and limits.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.