用 AI 改图时,最麻烦的地方通常不是“让模型生成一张图”,而是“只改一个细节,其他地方尽量别动”。
比如有一张人物照片,整体构图、姿势、光线都很好,只想把“绿色衬衫”改成“紫色卫衣”。如果直接用自然语言描述,很容易写成这样:
保持人物姿势、背景、构图、光线不变,把绿色衬衫改成紫色卫衣。
这句话看似清楚,但对图像模型来说仍然不够稳定。模型可能顺手改掉发型、背景、脸部细节,甚至重新组织整张画面。原因是自然语言描述是连续的一段话,所有信息混在一起,模型不容易区分哪些是必须保留的,哪些是允许修改的。
更稳的办法是:先让 Gemini 3 把图片拆成 JSON,再修改 JSON 里的目标字段,最后用修改后的 JSON 重新生成或编辑图片。
整个流程可以理解成“把图片变成可编辑菜单”。
flowchart LR
A[上传参考图片] --> B[Gemini 3 解析图片]
B --> C[生成结构化 JSON]
C --> D[修改目标字段]
D --> E[把修改后的 JSON 交给图像模型]
E --> F[生成新图或编辑原图]
JSON 的价值不在于它有什么特殊魔法,而在于它把图像信息拆成了清晰的字段:人物是谁、穿什么衣服、站在哪里、画面是什么比例、灯光是什么方向、镜头是什么焦段、哪些元素必须保留。这样改图时不需要重新描述整张图片,只需要改对应字段。
为什么 JSON 比普通 Prompt 更适合控图
普通 Prompt 是一段连续文本,适合从零生成图片;JSON 更适合在已有图片基础上做局部修改。
| 方式 | 适合场景 | 问题 |
|---|---|---|
| 普通自然语言 Prompt | 从零描述一张图 | 信息容易混在一起,局部修改时容易牵动其他元素 |
| JSON 描述 | 拆解已有图片、局部改图、复用风格 | 需要先设计字段结构,描述过细会增加 token 成本 |
| 原图 + JSON | 保持主体和构图,只改局部内容 | 仍可能出现细节漂移,需要加保留约束 |
| JSON 单独生成 | 复刻构图、风格、场景氛围 | 没有原图约束时,相似度通常不如“原图 + JSON” |
把图片变成 JSON 后,修改会从“写一大段模糊描述”变成“改一个字段值”。
例如原来有一个字段:
"upper_clothing": {
"type": "衬衫",
"color": "绿色",
"material": "棉质",
"fit": "宽松"
}
只想改衣服,就改成:
"upper_clothing": {
"type": "卫衣",
"color": "紫色",
"material": "柔软棉混纺",
"fit": "宽松"
}
其他字段不动,模型就更容易理解:人物、姿势、背景、镜头、光线都保持原样,只替换上衣。
第一步:让 Gemini 3 把图片转换成 JSON
把图片上传给 Gemini 3,然后要求它输出结构化描述。重点有三个:
- 只输出合法 JSON,不要夹杂解释文字。
- 保留英文 key,便于后续脚本处理或二次编辑。
- 字段值用中文描述,方便人工直接修改。
可直接使用这个 Prompt:
请分析我上传的图片,并将图片内容转换为一个结构化 JSON。
要求:
1. 只输出合法 JSON,不要输出 Markdown 代码块,不要解释。
2. JSON 的 key 使用英文。
3. JSON 的 value 使用中文描述。
4. 尽量保留图片中的主体、服装、姿势、表情、场景、构图、光线、色彩、镜头、风格和细节。
5. 如果图片中有文字,请放入 text_elements 字段。
6. 如果某个信息无法判断,请写“无法判断”,不要编造。
7. 包含图片尺寸、画面比例和适合后续改图的约束信息。
建议 JSON 结构如下:
{
"image_size": {},
"aspect_ratio": "",
"main_subject": {},
"clothing": {},
"pose_and_expression": {},
"scene": {},
"composition": {},
"lighting": {},
"color_palette": {},
"camera": {},
"style": {},
"text_elements": [],
"important_details": [],
"must_keep": [],
"editable_elements": [],
"negative_prompt": []
}
如果希望 JSON 更稳定,可以让 Gemini 3 按固定结构填充,而不是让模型自由发挥字段名。字段越固定,后面批量修改和复用越方便。
一个较完整的输出可能长这样:
{
"image_size": {
"width": 1024,
"height": 1365,
"unit": "px"
},
"aspect_ratio": "3:4",
"main_subject": {
"type": "年轻女性",
"age_range": "20 到 30 岁",
"hair": "深色中长发,自然垂落",
"face": "五官清晰,妆容自然",
"body_position": "正面略微侧身站立"
},
"clothing": {
"upper_clothing": {
"type": "衬衫",
"color": "绿色",
"material": "棉质或亚麻质感",
"fit": "略宽松"
},
"lower_clothing": {
"type": "长裤",
"color": "浅色",
"material": "柔软布料",
"fit": "自然垂坠"
},
"accessories": []
},
"pose_and_expression": {
"pose": "自然站立,一只手靠近身体侧面",
"expression": "平静、自然",
"eye_direction": "看向镜头"
},
"scene": {
"location": "室内空间",
"background": "简洁背景,细节较少",
"props": []
},
"composition": {
"framing": "半身到七分身构图",
"subject_position": "主体位于画面中央",
"camera_angle": "平视角度",
"background_blur": "轻微虚化"
},
"lighting": {
"type": "柔和自然光",
"direction": "从画面一侧照射",
"contrast": "低对比度",
"shadow": "阴影柔和"
},
"color_palette": {
"dominant_colors": ["绿色", "浅米色", "肤色", "深棕色"],
"tone": "干净、柔和、自然"
},
"camera": {
"shot_type": "人像摄影",
"lens": "标准人像镜头效果",
"depth_of_field": "中等景深",
"quality": "高清、细节自然"
},
"style": {
"visual_style": "真实摄影风格",
"mood": "清爽、自然、日常",
"rendering": "写实"
},
"text_elements": [],
"important_details": [
"保持人物姿势自然",
"保持背景简洁",
"保持柔和光线",
"保持真实摄影质感"
],
"must_keep": [
"人物身份和脸部特征",
"整体构图",
"背景位置关系",
"光线方向",
"画面比例"
],
"editable_elements": [
"上衣颜色",
"上衣款式",
"配饰",
"背景颜色",
"整体色调"
],
"negative_prompt": [
"不要改变人物脸部",
"不要改变人物姿势",
"不要增加多余人物",
"不要改变画面比例",
"不要出现明显 AI 伪影"
]
}
这个 JSON 已经把图片拆成了多个可控模块。想改衣服,就改 clothing.upper_clothing;想改背景,就改 scene.background;想改光线,就改 lighting;想保持某些内容不变,就写进 must_keep 和 negative_prompt。
第二步:只修改目标字段
假设目标是把绿色衬衫改成紫色卫衣,其他内容尽量不变。不要整段重写 JSON,只改相关字段。
修改前:
"upper_clothing": {
"type": "衬衫",
"color": "绿色",
"material": "棉质或亚麻质感",
"fit": "略宽松"
}
修改后:
"upper_clothing": {
"type": "卫衣",
"color": "紫色",
"material": "柔软棉混纺,有轻微绒感",
"fit": "略宽松"
}
同时可以在 JSON 末尾加一个明确的修改说明,告诉模型本次任务的边界:
"change_request": {
"target": "clothing.upper_clothing",
"operation": "replace",
"from": "绿色衬衫",
"to": "紫色卫衣",
"keep_unchanged": [
"人物脸部",
"人物发型",
"人物姿势",
"下装",
"背景",
"构图",
"光线方向",
"真实摄影风格"
]
}
这样做比只写“把衣服改成紫色卫衣”更清楚,因为模型能看到明确的目标路径、替换内容和保留清单。
用修改后的 JSON 生成图片
如果是基于原图编辑,应该同时提供原图和修改后的 JSON。Prompt 可以这样写:
请根据上传的原图和下面的 JSON 进行图像编辑。
编辑规则:
1. 以原图为主体参考。
2. 严格按照 change_request 修改指定元素。
3. must_keep 中列出的内容必须尽量保持一致。
4. negative_prompt 中列出的内容不要出现。
5. 除 change_request 指定内容外,不要主动改动其他元素。
6. 输出一张自然、真实、细节协调的新图。
JSON:
{在这里粘贴修改后的 JSON}
如果不上传原图,只提供 JSON,模型会根据结构化描述重新生成一张相似风格的图片,但不应该期待它和原图完全一致。两种模式的区别很重要:
| 模式 | 输入 | 适合任务 | 可控性 |
|---|---|---|---|
| 原图 + 修改后 JSON | 原图、JSON | 局部换衣、换背景、改颜色 | 更容易保持原主体 |
| 仅 JSON | JSON | 生成相似构图、复用风格描述 | 更像重新创作,细节会变化 |
| 原图 + 简短 Prompt | 原图、一句话需求 | 简单颜色替换 | 对复杂元素约束不够 |
| 多轮自然语言修改 | 原图、多次对话 | 临时试效果 | 容易越改越偏 |
推荐使用的 JSON 字段结构
为了让图像修改更稳定,可以把 JSON 分成三类字段:描述字段、约束字段、修改字段。
flowchart TB
A[图像 JSON] --> B[描述字段]
A --> C[约束字段]
A --> D[修改字段]
B --> B1[主体 main_subject]
B --> B2[服装 clothing]
B --> B3[场景 scene]
B --> B4[构图 composition]
B --> B5[光线 lighting]
B --> B6[风格 style]
C --> C1[must_keep]
C --> C2[negative_prompt]
C --> C3[quality_constraints]
D --> D1[change_request]
D --> D2[target]
D --> D3[operation]
D --> D4[keep_unchanged]
常用字段可以按这个表设计:
| 字段 | 作用 | 示例 |
|---|---|---|
image_size | 记录尺寸 | {"width": 1024, "height": 1365} |
aspect_ratio | 控制画面比例 | "3:4" |
main_subject | 描述主体 | 人物、动物、产品、建筑 |
clothing | 描述服装 | 上衣、下装、鞋子、配饰 |
pose_and_expression | 控制姿势表情 | 站立、微笑、看向镜头 |
scene | 描述环境 | 室内、街道、海边、办公室 |
composition | 描述构图 | 居中、特写、俯拍、平视 |
lighting | 描述光线 | 柔光、逆光、侧光、低对比 |
color_palette | 控制色彩 | 主色、辅助色、整体色调 |
camera | 控制摄影语言 | 焦段、景深、机位 |
style | 控制视觉风格 | 写实、插画、电影感 |
text_elements | 记录画面文字 | 海报标题、标牌、字幕 |
must_keep | 强制保留项 | 脸部、姿势、背景、构图 |
editable_elements | 允许修改项 | 衣服、背景、颜色 |
negative_prompt | 避免出现的问题 | 变脸、多手指、文字乱码 |
change_request | 本次具体修改 | 把绿色衬衫换成紫色卫衣 |
精准改图的关键:把“保留”和“修改”分开写
很多改图失败,是因为 Prompt 只告诉模型“改什么”,没有告诉模型“别改什么”。
不稳定写法:
把图片里的绿色衬衫改成紫色卫衣。
更稳定写法:
只修改上衣:将绿色衬衫替换为紫色卫衣。
保持人物脸部、发型、姿势、下装、背景、构图、光线方向、画面比例不变。
不要增加新人物,不要改变场景,不要改变摄影风格。
放到 JSON 里可以这样写:
{
"change_request": {
"target": "clothing.upper_clothing",
"operation": "replace",
"from": {
"type": "衬衫",
"color": "绿色"
},
"to": {
"type": "卫衣",
"color": "紫色",
"material": "柔软棉混纺",
"details": "无明显大图案,简洁款式"
}
},
"must_keep": [
"人物脸部特征",
"人物发型",
"人物姿势",
"下装款式",
"背景结构",
"光线方向",
"画面比例",
"真实摄影风格"
],
"negative_prompt": [
"不要改变人物身份",
"不要改变脸型",
"不要改变背景",
"不要增加文字",
"不要增加多余肢体",
"不要让衣服边缘和身体错位"
]
}
这里的重点不是 JSON 格式本身,而是任务边界非常明确:target 表示改哪里,to 表示改成什么,must_keep 表示必须尽量保持,negative_prompt 表示不要出现什么。
常见改图任务模板
1. 换衣服
"change_request": {
"target": "clothing.upper_clothing",
"operation": "replace",
"from": "绿色衬衫",
"to": {
"type": "紫色卫衣",
"fit": "略宽松",
"material": "柔软棉混纺",
"details": "简洁无大面积印花"
},
"keep_unchanged": [
"人物脸部",
"发型",
"姿势",
"下装",
"背景",
"光线"
]
}
适合修改上衣、裙子、鞋子、帽子、包等具体物体。物体边界越清楚,成功率越高;如果衣服被头发、手臂、道具遮挡,模型需要重建被遮挡区域,细节漂移会更明显。
2. 换背景
"change_request": {
"target": "scene.background",
"operation": "replace",
"from": "简洁室内背景",
"to": {
"location": "现代咖啡馆",
"details": "木质桌椅、暖色灯光、背景轻微虚化",
"mood": "温暖、安静、日常"
},
"keep_unchanged": [
"人物",
"服装",
"姿势",
"面部特征",
"主体大小",
"主体位置"
]
}
换背景时要特别强调主体位置和主体大小,否则模型可能把人物重新缩放,导致画面不像同一张图。
3. 改色调
"change_request": {
"target": "color_palette",
"operation": "adjust",
"to": {
"tone": "秋日暖色调",
"dominant_colors": ["暖棕色", "米色", "浅橙色"],
"saturation": "中等偏低",
"contrast": "柔和"
},
"keep_unchanged": [
"主体内容",
"服装款式",
"背景结构",
"构图"
]
}
色调修改容易影响肤色和材质,所以可以补充:
"negative_prompt": [
"不要让肤色过黄",
"不要让阴影过重",
"不要改变衣服款式",
"不要改变背景结构"
]
4. 改风格
"change_request": {
"target": "style.visual_style",
"operation": "transform",
"from": "真实摄影风格",
"to": "柔和日系插画风格",
"style_constraints": {
"line": "干净细线条",
"color": "低饱和柔和色彩",
"texture": "轻微纸张质感",
"detail_level": "中等细节"
},
"keep_unchanged": [
"人物姿势",
"服装结构",
"背景布局",
"画面比例"
]
}
风格转换比换颜色更容易改变主体细节,因为模型需要重新绘制整张图。想保留人物身份时,要把脸部特征、发型、五官比例写进 must_keep。
用一份完整模板完成“反推 JSON → 修改 → 生成”
可以把工作拆成两个固定 Prompt。
Prompt A:图片转 JSON
请将上传的图片转换成结构化 JSON,用于后续图像编辑。
输出要求:
- 只输出合法 JSON。
- key 使用英文。
- value 使用中文。
- 不要输出解释、注释或 Markdown 代码块。
- 不确定的信息写“无法判断”。
- 尽量详细描述主体、服装、姿势、表情、场景、构图、光线、色彩、镜头、风格、文字元素和需要保留的细节。
JSON 结构:
{
"image_size": {
"width": "",
"height": "",
"unit": "px"
},
"aspect_ratio": "",
"main_subject": {
"type": "",
"count": "",
"appearance": "",
"hair": "",
"face": "",
"body_position": ""
},
"clothing": {
"upper_clothing": {
"type": "",
"color": "",
"material": "",
"fit": "",
"details": ""
},
"lower_clothing": {
"type": "",
"color": "",
"material": "",
"fit": "",
"details": ""
},
"shoes": "",
"accessories": []
},
"pose_and_expression": {
"pose": "",
"gesture": "",
"expression": "",
"eye_direction": ""
},
"scene": {
"location": "",
"background": "",
"props": [],
"environment_details": ""
},
"composition": {
"framing": "",
"subject_position": "",
"camera_angle": "",
"background_blur": "",
"perspective": ""
},
"lighting": {
"type": "",
"direction": "",
"contrast": "",
"shadow": "",
"highlight": ""
},
"color_palette": {
"dominant_colors": [],
"tone": "",
"saturation": "",
"contrast": ""
},
"camera": {
"shot_type": "",
"lens": "",
"depth_of_field": "",
"quality": ""
},
"style": {
"visual_style": "",
"mood": "",
"rendering": ""
},
"text_elements": [],
"important_details": [],
"must_keep": [],
"editable_elements": [],
"negative_prompt": []
}
Prompt B:根据修改后的 JSON 改图
请根据上传的原图和下面的 JSON 生成编辑后的图片。
执行要求:
1. 以原图为主体参考。
2. 只执行 change_request 中指定的修改。
3. must_keep 中的内容必须尽量保持一致。
4. negative_prompt 中的内容不要出现。
5. 除指定修改外,不要改变人物身份、姿势、背景结构、构图、光线方向和画面比例。
6. 生成结果要自然,修改区域与原图材质、光线、透视关系一致。
JSON:
{粘贴修改后的 JSON}
如果模型支持多轮对话,第一次输出 JSON 后,可以直接让它在 JSON 上做字段替换:
请只修改 JSON 中和上衣相关的字段:
- 把绿色衬衫改成紫色卫衣
- 保持人物、姿势、背景、光线、构图不变
只输出修改后的完整 JSON。
再把完整 JSON 交给图像生成或编辑功能即可。
让结果更稳定的几个技巧
字段不要互相冲突
如果 clothing.upper_clothing.color 写的是“紫色”,但 color_palette.dominant_colors 仍然保留“绿色”为主色,模型可能会在衣服、背景或整体色调中继续保留绿色。修改关键元素时,相关字段也要同步调整。
例如换衣服颜色时,最好同时检查:
"clothing": {},
"color_palette": {},
"important_details": [],
"must_keep": [],
"negative_prompt": []
保留项要具体
“保持不变”太宽泛,模型不知道重点在哪里。可以拆成具体对象:
"must_keep": [
"人物脸部特征",
"人物发型长度和颜色",
"人物站姿",
"画面中人物的位置",
"背景墙面和家具布局",
"从左侧进入的柔和光线",
"3:4 画面比例"
]
越具体,模型越容易遵守。
修改范围要尽量小
如果一次同时要求换衣服、换背景、改发型、改风格,模型基本会重新生成整张图,保留一致性会下降。更稳的方式是分轮处理:
flowchart LR
A[原图] --> B[换上衣]
B --> C[确认主体稳定]
C --> D[换背景]
D --> E[确认构图稳定]
E --> F[调整色调]
一次只改一个主要目标,便于判断哪一步导致画面漂移。
JSON 不要无限变长
描述越详细,不一定越好。过长的 JSON 可能让模型抓不到重点,也会增加输入成本。对改图最有用的信息通常集中在这些字段:
main_subject
clothing
scene
composition
lighting
style
must_keep
negative_prompt
change_request
如果只是换衣服,没必要详细描述每一处背景纹理;如果只是换背景,没必要把衣服材质写到非常细。
给模型明确的输出目标
“根据 JSON 生成图片”和“根据原图编辑图片”不是同一个任务。要避免混淆:
错误倾向:
根据 JSON 画一张图。
更清楚:
以原图为参考,只把上衣替换为 JSON 中指定的紫色卫衣,其余元素尽量保持原图一致。
前者更像重新创作,后者才是局部编辑。
常见问题和处理方法
| 问题 | 可能原因 | 处理方式 |
|---|---|---|
| 衣服改了,但脸也变了 | 没有把脸部写入 must_keep | 增加“人物脸部特征、五官比例、发型保持不变” |
| 背景被一起改掉 | 修改范围不明确 | 在 keep_unchanged 中写入背景结构、光线方向、构图 |
| 紫色卫衣变成紫色衬衫 | type 和 details 描述不够 | 写明“连帽卫衣、罗纹袖口、柔软棉混纺、不是衬衫” |
| 生成结果像重绘,不像编辑 | 只用了 JSON,没有上传原图 | 使用“原图 + 修改后 JSON” |
| 模型忽略 JSON 中部分字段 | 字段太多或互相矛盾 | 精简 JSON,保留关键字段,消除冲突 |
| 出现多余文字或图案 | 没有限制图案和文字 | 在 negative_prompt 中加入“不要出现文字、Logo、大面积印花” |
| 画面比例变化 | 没有固定尺寸或比例 | 在 image_size 和 aspect_ratio 中写清楚,并放入 must_keep |
一个可复用的最小 JSON 模板
日常改图不一定需要完整大 JSON。只做局部替换时,用这个最小模板就够了:
{
"aspect_ratio": "3:4",
"main_subject": {
"description": "保持原图中的人物身份、脸部特征、发型、姿势和主体位置"
},
"scene": {
"description": "保持原图背景、构图和光线方向"
},
"style": {
"description": "保持真实摄影风格,画面自然,细节清晰"
},
"change_request": {
"target": "clothing.upper_clothing",
"operation": "replace",
"from": "绿色衬衫",
"to": "紫色卫衣"
},
"must_keep": [
"人物脸部",
"发型",
"姿势",
"下装",
"背景",
"构图",
"光线方向",
"画面比例"
],
"negative_prompt": [
"不要改变人物身份",
"不要改变背景",
"不要增加文字",
"不要增加多余人物",
"不要出现明显 AI 伪影"
]
}
搭配编辑 Prompt:
请基于上传的原图进行局部编辑,只执行 JSON 中的 change_request。
必须保持 must_keep 中列出的内容,不要出现 negative_prompt 中的问题。
请让修改后的衣服与原图的身体姿态、光线、阴影和材质关系自然匹配。
JSON:
{粘贴 JSON}
适合用 JSON 控图的场景
JSON 控图适合“已有图片很好,只想改局部”的任务。
| 场景 | 是否适合 | 说明 |
|---|---|---|
| 换衣服颜色或款式 | 适合 | 目标明确,字段容易定位 |
| 换产品外壳颜色 | 适合 | 产品结构可写入 must_keep |
| 换背景 | 适合 | 需要固定主体位置和光线 |
| 调整海报风格 | 适合 | 可以把版式、色彩、文字拆开 |
| 大幅改变人物动作 | 不太适合 | 姿势变化会牵动身体结构,容易重绘 |
| 精准还原同一张脸 | 有难度 | 需要原图强参考,仍可能漂移 |
| 一次改很多元素 | 不稳定 | 容易变成重新生成 |
| 要求像素级一致 | 不适合 | 图像模型通常不能保证像素级编辑 |
核心思路
Gemini 3 的 JSON 控图流程,本质上是把图片拆成结构化信息,再用字段修改替代大段自然语言描述。
最重要的不是 JSON 写得多复杂,而是做到三件事:
- 把图像元素拆开:主体、服装、背景、光线、构图、风格分别描述。
- 把修改目标写准:用
change_request.target指定改哪个字段。 - 把保留项写具体:用
must_keep和negative_prompt限制模型不要乱改。
当图片描述变成可编辑结构后,改图就不再依赖反复解释整张图,而是像修改配置文件一样,找到对应字段,替换关键词,再交给模型生成结果。