环境搭建

1. 安装Stable Diffusion WebUI

我通过拉取github里的SD仓库并运行完成了Stable Diffsuion本地的初步部署。

2. 下载模型和ControlNet

在图像生成的模型选择上,我选择了ToonYou模型,原因是:

        这个项目做的是童话绘本,不是写实照片,也不是二次元动漫。ToonYou的风格介于迪士尼和儿童绘本之间——色彩温暖、线条柔和、角色表情丰富,非常适合这个场景。

        如果选写实模型,生成的“小男孩”可能会像真人照片,不符合绘本的预期风格。如果选动漫模型,又太“日系”,少了绘本的质感。、

除此之外,我安装了controlnet的插件,controlnet可以在不破坏原有SD模型能力的前提下,给它加一个“额外的输入通道”,让SD模型在生成图像是会参考controlnet传入的图片。

ControlNet模型ip-adapter-plus_sd15(这里因为ToonYou是基于SD1,5的模型,所以IP-adapter也要相应版本)

  • 用于保持角色一致性,这是实现"同一个主角"的关键

3. 启动API服务

在WebUI启动时添加 --api 参数:

python launch.py --api --listen

这样就完成了本地的部署并能够调用相应api了!

初步生成图像

完成环境搭建后,接下来就是如何调用SD的API来生成图像。我把代码分成四个文件,各司其职:

文件 职责
config.py 集中管理所有配置参数
generator.py 核心生成器类,封装SD API调用
Image_generator.py 对外接口层,提供简洁的调用函数
test.py 测试脚本,验证功能

一、配置文件:config.py

config.py 是整个模块的“控制面板”。因为我会生成各种不同的角色,所以提示词不能写死具体特征,而是要从“风格”和“质量”两个维度来约束:

1. 通用风格提示词

GENERIC_STYLE = """
high quality, detailed, beautiful composition, vibrant colors, 
clear subject, well-lit, appealing characters
"""

这个风格提示词的核心作用是定调。它告诉SD:我要的是高质量、细节丰富、色彩鲜艳、构图美观的图片。无论生成什么角色、什么场景,这个“画风基线”都要保持。

为什么不用“children's book illustration style”这类具体风格?因为后续可能生成不同风格的绘本,把风格写死在config里反而限制了扩展性。所以我只保留了通用画质要求,具体的风格描述由调用时的prompt传入。

2. 通用负向提示词

GENERIC_NEGATIVE = """
blurry, low quality, ugly, distorted, bad anatomy, watermark, text,
cropped, out of frame, extra fingers, mutated hands, missing fingers,
extra limbs, bad proportions, duplicate, weird colors
"""

负向提示词的作用是排除常见缺陷。SD在生成图像时经常出现畸形手指、多余肢体、模糊、水印等问题,把这些统统写进负向提示词,可以大幅提高生成质量。

这里面有几个关键项:

  • bad anatomy, extra fingers, mutated hands:针对SD最著名的“画手难题”

  • watermark, text:避免生成带有版权标记或乱码文字的图

  • blurry, low quality:强制要求清晰度

二、核心生成器:generator.py 

generator.py 里的 ImageGenerator 类负责所有与SD API的交互。其中最关键的就是ControlNet的集成。

调用ControlNet的核心步骤

在 generate 方法中,如果调用时传入了 character_id,就去读取对应的参考图,然后构建一个ControlNet单元:

  1. 读取参考图并转base64:SD API要求图片以base64字符串形式传递,不能直接传文件路径。

  2. 指定module和modelip-adapter_auto 是预处理模块,ip-adapter-plus_sd15 是具体模型。注意模型版本要和SD主模型匹配——ToonYou基于SD1.5,所以IP-Adapter也要用sd15版本。

  3. 设置weight权重:控制参考图的影响力。weight=1.0表示正常参考,调高会让角色更像参考图但可能动作僵硬,调低则角色容易变形。

  4. 设置guidance_start和guidance_end:都设为0.0和1.0,表示ControlNet在整个生成过程中全程生效。

三、对外接口:Image_generator.py 的封装

Image_generator.py 是对外提供的调用入口,采用单例模式——整个应用只有一个Generator实例,避免重复初始化SD连接。它对外暴露的函数都很简洁,调用方不需要知道ImageGenerator类的内部细节。

这里重点说一下提示词的封装思路

如果让调用方直接拼接完整的prompt字符串,会带来两个问题:

  • 调用方必须了解SD提示词的写法规范(比如哪些词在前、权重怎么加)

  • 角色动作和场景描述的拼接逻辑会散落在各个调用处,难以统一修改

所以我设计了两层封装:

第一层:将生成参数结构化

对外提供的 generate_image 函数不接收完整的prompt,而是接收两个独立参数:action 和 scene

def generate_image(action: str, scene: str, character_id: str = None, ...):
    prompt = f"{action}, {scene}"
    # 再自动追加通用风格提示词
    full_prompt = f"{prompt}, {config.GENERIC_STYLE}"
    ...

调用方只需要说“做什么动作”和“在什么场景”,比如:

  • action = "a cute cat sitting"

  • scene = "on a chair, cartoon style"

函数内部会自动拼接成完整的prompt,并追加配置中的通用风格。这样做的好处:

  • 调用方不需要学习提示词工程,只需要描述画面内容

  • 风格控制集中在配置文件中,换风格不用改业务代码

  • 动作和场景分离,后续如果要从AI Agent生成的剧本中自动提取,解析起来也更方便

第二层:批量生成的结构化输入

批量生成函数 generate_batch 接收一个 pages 列表,每个元素是一个字典:

pages = [
    {"action": "a little boy standing", "scene": "in a magical forest"},
    {"action": "the same boy running", "scene": "through a flower field"},
]

这种结构化的输入格式,天然对接后续AI Agent的输出——大语言模型生成的剧本可以直接转换成这个格式,无需额外解析。

单例模式的考虑

_get_generator() 函数确保全局只有一个 ImageGenerator 实例。这是因为SD API的连接和模型切换有一定开销,重复初始化没有必要。同时,角色参考图保存在实例的目录属性中,单例可以保证多次调用之间参考图路径一致。

至于test脚本是目前测试用,故不作介绍。

总结与后续计划

当前成果回顾

到这一步为止,我已经完成了绘本生成器的图像模块基础建设:

  1. 环境搭建:Stable Diffusion WebUI 本地部署,ToonYou 模型配置,ControlNet IP-Adapter 安装,API 服务启动

  2. 代码架构:config(配置管理)、generator(核心生成逻辑)、Image_generator(对外接口)、test(测试验证)四个模块分层清晰

  3. 基础功能:单张图像生成、角色参考图上传与管理、ControlNet 初步集成、批量生成接口

目前已经可以实现:给定一段提示词,生成一张质量尚可的图片;如果上传了角色参考图,同一角色的多张生成结果在长相上有一定的相似度。

但这个“一定的相似度”离真正的角色一致性还有距离。后续需要在三个方向上深入优化。

一、角色控制的优化

当前问题

虽然 ControlNet 已经接入了,但同一个角色在不同画面中仍然会出现特征飘移——比如这一页的男孩头发偏棕,下一页偏黑;这一页眼睛大而圆,下一页眼睛细长。

二、提示词架构的优化

当前问题

目前的提示词是“通用风格 + 用户传入的动作和场景”简单拼接。这种方式的缺点是:

  • 不同场景需要重复写相同的画质要求

  • 难以针对不同角色类型动态调整提示词

  • 提示词过长可能稀释关键信息

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐