芥末
发布于 2025-12-24 / 0 阅读
0
0

Gemini 3 用 JSON 做精准控图:从图片反推描述再局部改图

用 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,然后要求它输出结构化描述。重点有三个:

  1. 只输出合法 JSON,不要夹杂解释文字。
  2. 保留英文 key,便于后续脚本处理或二次编辑。
  3. 字段值用中文描述,方便人工直接修改。

可直接使用这个 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_keepnegative_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局部换衣、换背景、改颜色更容易保持原主体
仅 JSONJSON生成相似构图、复用风格描述更像重新创作,细节会变化
原图 + 简短 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 中写入背景结构、光线方向、构图
紫色卫衣变成紫色衬衫typedetails 描述不够写明“连帽卫衣、罗纹袖口、柔软棉混纺、不是衬衫”
生成结果像重绘,不像编辑只用了 JSON,没有上传原图使用“原图 + 修改后 JSON”
模型忽略 JSON 中部分字段字段太多或互相矛盾精简 JSON,保留关键字段,消除冲突
出现多余文字或图案没有限制图案和文字negative_prompt 中加入“不要出现文字、Logo、大面积印花”
画面比例变化没有固定尺寸或比例image_sizeaspect_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 写得多复杂,而是做到三件事:

  1. 把图像元素拆开:主体、服装、背景、光线、构图、风格分别描述。
  2. 把修改目标写准:用 change_request.target 指定改哪个字段。
  3. 把保留项写具体:用 must_keepnegative_prompt 限制模型不要乱改。

当图片描述变成可编辑结构后,改图就不再依赖反复解释整张图,而是像修改配置文件一样,找到对应字段,替换关键词,再交给模型生成结果。


评论