第 5 篇把"从零生成一张图"讲完了:模型选型、文生图提示词、尺寸与质量参数。但生产里的图像需求,一大半不是凭空生成,而是改已有的图——电商要把产品图批量换成节日氛围背景,家谱项目要修复扫描的老照片,运营要让同一角色出现在十张不同海报里。改一张是功能,改一批且改得稳、改得便宜,才是工程。本篇是《多模态开发实战》第 6 篇,按"三种编辑模式 → 指令式与掩码实战 → 多图融合 → 批量并发工程 → 两段式成本 → 提示词与修图循环"组织全文。文中能力与计费均为 2026 年 10 月各家官方文档口径。
1、图像编辑三种模式
图像编辑 API 的形态已经收敛成三种,先把名字和边界定清楚。
指令式编辑:原图加一句自然语言指令,模型自己定位该改哪里。"把背景换成雪山"就是典型——不圈选、不画蒙版,改哪儿由模型判断。这是当前的主流形态,gpt-image-1 的 edits 端点、Gemini 图像模型、FLUX.1 Kontext、Qwen-Image-Edit 都走这条路。
区域重绘(inpainting):用一张掩码(mask)显式圈定重绘区域,掩码之外的像素原样保留。代价是要准备掩码,收益是像素级保形——证件照换底色时人脸一个像素都不该动,这种需求只有掩码能满足。
多图融合:多张参考图加指令合成一张新图。风格迁移是"内容图 + 风格图",角色一致是"角色参考图 + 新场景描述",产品置景是"产品图 + 场景图"。各家支持现状对照如下:
| 模型 | 指令式 | 掩码重绘 | 多图融合 |
|---|---|---|---|
| gpt-image-1 | ✅ | ✅ 透明 PNG | ✅ 多图输入 |
| Gemini 图像系 | ✅ 多轮对话 | ❌ 无掩码参数 | ✅ 数张参考图 |
| FLUX.1 Kontext | ✅ | ❌ 无原生掩码 | dev 单图为主 |
| Qwen-Image-Edit | ✅ 中文改字强 | ❌ 以指令为主 | ✅ 多图合成 |
表中 Gemini 图像系指 2.5 Flash Image 与 3 Pro Image;FLUX 的 dev 版是开源 12B 权重,max 版走商业 API。选型原则一句话:指令式优先,要像素级保形才上掩码,要跨图一致就走多图融合。
把这条原则画成分支图:
两个判断都是特化出口:命中才走,不命中一律落回指令式——它也是上表中唯一四家模型全支持的模式。
2、指令式编辑实战
指令式编辑的调用面很薄:一个端点、一张图、一段提示词。以 gpt-image-1 给运动鞋换雪山背景为例,接口见 OpenAI 图像指南:
# edit_bg.py —— 产品图换背景(gpt-image-1)
import base64
from openai import OpenAI
client = OpenAI()
result = client.images.edit(
model="gpt-image-1",
image=[open("sneaker.jpg", "rb")], # 原图,列表可传多张
prompt="把运动鞋放在雪山前的雪地上,保留鞋型、配色与商标细节,"
"冷色柔光,商业产品摄影,背景轻度虚化",
size="1024x1024",
quality="medium", # 先看效果再出高清
)
open("sneaker_snow.png", "wb").write(
base64.b64decode(result.data[0].b64_json))
解读:prompt 写的是整张最终画面,不是"把背景改掉"这种差量描述——编辑模型按目标图理解指令,差量描述容易触发整图重绘。保真约束要显式列出来:鞋型、配色、商标三项写进提示词,模型才会在重绘背景时守住主体。
老照片修复是同一端点换 prompt:去除划痕与噪点、黑白照片自然上色、修补破损区域,同时"保持人物五官、发型与衣物纹理不变"。修复类任务的通病是模型好心把人修年轻——把年龄特征也写进保真清单,能有效压住这类自作主张。
3、掩码重绘与工具链
掩码语义是新手最容易搞反的地方。gpt-image-1 的口径是:掩码为与原图同尺寸的 PNG,完全透明(alpha 为 0)的区域是重绘区,不透明区域原样保留——与"涂黑表示要改"的直觉正好相反。
注意:掩码必须与原图同尺寸;并且最好在提示词里点出重绘区要画什么,模型对掩码内容的推断并不总是稳定。
坐标已知的场景(固定版式去水印、标题条替换)用代码生成掩码最省事,生成与调用一气呵成:
# mask_edit.py —— 坐标掩码 + 带 mask 的编辑调用
from PIL import Image, ImageDraw
from openai import OpenAI
import base64
client = OpenAI()
mask = Image.new("RGBA", (1024, 1024), (0, 0, 0, 255)) # 不透明=保留
draw = ImageDraw.Draw(mask)
draw.rectangle([320, 40, 700, 120], fill=(0, 0, 0, 0)) # 透明=重绘
mask.save("mask.png")
result = client.images.edit(
model="gpt-image-1",
image=[open("poster.jpg", "rb")],
mask=open("mask.png", "rb"),
prompt="海报整体不变,标题条区域重绘为金色艺术字「周年庆典」",
size="1024x1024",
)
open("poster_new.png", "wb").write(
base64.b64decode(result.data[0].b64_json))
解读:掩码来源按场景分三路。规则区域用 PIL 画,坐标写在配置里可复用;人工圈选交给 labelme 或 GIMP,导出透明 PNG 即可;主体掩码交给抠图模型——rembg 一行代码抠出主体 alpha 通道,反转即得"除主体外全部重绘"的背景掩码,这是证件照换底色、产品图换背景的固定链路。
4、多图融合与角色一致
跨图一致性的需求——同一角色出现在系列配图里、全站封面统一画风——只能靠参考图解决。Gemini 图像模型的多参考图接口最顺手,双图融合示例如下:
# fuse.py —— 角色图 + 风格图融合(Gemini)
from google import genai
from google.genai import types
client = genai.Client()
def part(path):
return types.Part.from_bytes(
data=open(path, "rb").read(), mime_type="image/png")
resp = client.models.generate_content(
model="gemini-2.5-flash-image",
contents=[
part("hero.png"), # 角色参考:锁定主角长相
part("style.png"), # 风格参考:水彩绘本画风
"把第一张图的角色画进雨天车站,整体画风与配色"
"参考第二张图,保持角色五官和服装一致",
],
)
img = next(p for p in resp.candidates[0].content.parts
if p.inline_data)
open("hero_station.png", "wb").write(img.inline_data.data)
解读:参考图的顺序就是指代——提示词里"第一张图""第二张图"按 contents 顺序对号,比"左图右图"稳定得多。角色一致要满足两个条件:角色参考图放在最前,五官与服装约束显式写进指令。gpt-image-1 的 edits 端点传多元素 image 列表是同款玩法;要自部署,开源的 Qwen-Image-Edit 与 FLUX.1 Kontext dev 都支持参考图输入,前者在中文场景的文字替换尤其好使。
5、批量并发生产工程
单张出图是一次 API 调用,一百张出图是系统工程。第一个现实是限速:图像接口按账号档位限制每分钟图片数与 token 数,gpt-image-1 低档位每分钟只有个位数到几十张,详见 OpenAI 限速文档,超了就是 429。
批量任务里 429 与偶发 5xx 是常态而不是异常,重试逻辑要在第一天就写进代码,而不是等线上炸了再补。
批量的骨架是三件套:信号量控并发、指数退避重试、确定性落盘加清单。核心实现如下:
# batch.py —— 并发池 + 退避重试 + 落盘清单
import asyncio, base64, json
from openai import AsyncOpenAI
client = AsyncOpenAI()
sem = asyncio.Semaphore(4) # 并发数取限速的 6~8 折
async def gen_one(task):
async with sem:
for i in range(4): # 最多重试 4 次
try:
r = await client.images.generate(
model="gpt-image-1", prompt=task["prompt"],
size="1024x1024", quality="low") # 草稿档
path = f"out/{task['id']}.png"
open(path, "wb").write(
base64.b64decode(r.data[0].b64_json))
open("manifest.jsonl", "a", encoding="utf-8").write(
json.dumps({**task, "path": path},
ensure_ascii=False) + "\n")
return True
except Exception:
await asyncio.sleep(2 ** i) # 指数退避
return False
async def main(tasks):
done = await asyncio.gather(*map(gen_one, tasks))
print(f"完成 {sum(done)}/{len(tasks)}")
asyncio.run(main(json.load(open("tasks.json", encoding="utf-8"))))
三个工程决策值得展开。并发数取限速的六到八成:顶格配额会因瞬时抖动触发限速,退避重试反而更慢。失败任务不吞掉:gather 的结果里把返回 False 的任务回写 failed.json,修完参数二次跑。manifest 记全参数:prompt、模型、尺寸、落盘路径全在清单里,效果不可复现时能对账,筛选阶段也能按 id 关联产物。
6、两段式成本控制
图像按张计费,价差主要在质量档:gpt-image-1 的 low 档 1024 方图一美分级,high 档约 0.17 美元,1536 宽幅高质量约 0.25 美元——高低档价差十几倍。Gemini 2.5 Flash Image 每张约 0.039 美元,质量更高的 3 Pro Image 更贵。
批量的正确姿势是两段式:草稿档全量出候选,人工或视觉模型筛出入围者,只对入围的付高清价。
| 阶段 | 参数 | 单张成本 | 用途 |
|---|---|---|---|
| 草稿 | gpt-image-1 low、1024 方图 | 约 $0.011 | 试 prompt、出候选 |
| 交付 | gpt-image-1 high、1536 宽幅 | 约 $0.25 | 最终产物 |
算一笔账:10 个候选选 1,直接全高清要 2.5 美元起;两段式是 0.11 美元草稿加 0.25 美元交付,约七分之一的成本。候选数越多,杠杆越大。另一条路线是模型错配:草稿用便宜的 gpt-image-1-mini 或 Gemini 2.5 Flash Image,交付用高质量档,代价是两段画风有差异,风格敏感的任务慎用。
7、提示词进阶与修图循环
负面提示词是老习惯:SD 系有 negative_prompt 参数,但 gpt-image-1、Gemini、FLUX Kontext 都没有这个参数。替代法三条:一是正向描述目标态,"干净纯白背景"永远优于"不要杂乱背景",模型对"要什么"的服从性远高于"不要什么";二是否定短语直接写进正向提示词,gpt-image-1 对 without text、"无文字水印"这类表述理解得不错;三是把要避开的元素用掩码圈出重绘范围,物理隔离最可靠。
第二个进阶点是对话式修图:不追求一次写完美 prompt,而是生成、看图、追加指令、再编辑的循环。Gemini 图像模型原生支持多轮,代码如下:
# refine.py —— 多轮对话式修图(Gemini)
from google import genai
from google.genai import types
client = genai.Client()
contents = [types.Part.from_bytes(open("sneaker.jpg", "rb").read(),
"image/jpeg"),
"把背景换成雪山"]
for tweak in ["雪面太灰,加午后阳光", "鞋底阴影再自然些"]:
contents.append(tweak)
resp = client.models.generate_content(
model="gemini-2.5-flash-image", contents=contents)
img = next(p for p in resp.candidates[0].content.parts
if p.inline_data)
contents.append(img) # 新图回传,保持上下文
open(f"step{len(contents)}.png", "wb").write(img.inline_data.data)
解读:每轮把最新生成的图回传进对话,模型基于自己刚画的图理解差量指令,比每次从原图重新描述稳定得多。循环里的"看图"环节可以交给人,也可以交给视觉模型——第 3 篇的读图能力正好补上自动批评:让模型按"主体是否保真、构图是否达标"打分,不达标就自动生成下一轮修改指令。生成、感知、决策闭环,这就是一个最小可行的多模态 Agent,第 11 篇会正式展开。
一个省钱的细节:多轮历史的对话里只保留最新一张图,旧图全部丢弃——图像 token 在多轮里是累加的,这个习惯第 3 篇已经论证过。
8、总结
回顾全文:编辑三模式按"指令式优先、保形上掩码、一致走多图"选型;指令式的 prompt 写整张目标图,配显式保真约束;掩码语义是透明区重绘,来源分代码、人工、抠图模型三路;多图融合靠参考图顺序指代与显式一致性约束;批量工程三件套是信号量、退避重试与 manifest 清单;成本闸门是两段式——草稿档全量试,只为入围者付高清价;没有负面提示词的家用正向目标态加否定短语补位。
留一个练习:做一条"10 个章节配图"的两段式流水线。把章节标题与要点写成 tasks.json,草稿档批量出 10 张;用视觉模型按"贴合主题、无文字乱码"打分,淘汰一半;入围的 5 章换 high 质量 1536 宽幅重出,全程写 manifest。做完会同时用上并发池、重试、清单与两段式,本篇知识点全部过手一遍。
对于图像需求进入量产期的团队,建议先把第 5 节的批量骨架跑通再谈效果调优——稳定性是批量的第一属性,prompt 打磨是第二位的事。

