拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Photoshop内嵌AI绘画工作流:LoRA预览与图生图实战

1. 项目背景为什么需要重构 AI 绘画工作流AI 绘画早已不是“输入一句提示词、等一张图”的阶段。设计团队和参赛团队真正头疼的问题往往出在流程上生成工具是生成工具Photoshop 是 Photoshop两边来回倒图不仅浪费时间还容易丢细节。比如设计草图在 PS 里已经排好了图层、选区、蒙版但切到 WebUI 后这些信息全部丢失只能重新描述而 WebUI 里试好的 LoRA 权重、采样参数、种子值回到 PS 里又要靠手动记录换一台电脑就全部失效。从应用层看设计师希望在 PS 里完成构图、修改、合成同时希望 AI 生成结果能直接回到当前画布从模型层看LoRA 让风格和角色变得可控制但 LoRA 的数量变多后哪个 LoRA 适合哪张底图、权重调到多少合适不能靠每次跑完整张图来判断。这也是为什么“在 Photoshop 中集成 LoRA 预览图系统”会成为一套值得做的工程课题。本文以 B 站 AI 创造公开赛中常见的参赛方向为例拆解一套相对完整的本地 AI 绘画工作流在 PS 内接入 LoRA 预览能力串联 XL 图生图链路同时保留 krea2 这类文生图能力的扩展入口。适合阅读本文的读者有三类一是想把 Stable Diffusion 等生成能力装进 Photoshop 的设计师二是正在准备 AI 创作类比赛、需要输出一份可演示作品的开发者三是已经会跑 WebUI但受困于素材反复导入导出、LoRA 效果不可视化等问题的进阶用户。读完本文你可以自己搭出一套“先预览 LoRA、再用图生图精修、最后由文生图拓展灵感”的闭环流程。2. 核心概念与整体架构2.1 先分清三个术语LoRA、文生图、图生图要理解整套工作流第一步不是写代码而是把术语边界理清。LoRALow-Rank Adaptation低秩适配原本是一种高效的模型微调方法。在 Stable Diffusion 生态里LoRA 通常代表一个体积很小的模型文件例如几百 MB 甚至几十 MB。它不替换基础大模型而是作为一个“风格或角色插件”叠加到基础模型上。比如你有一个写实风格的基础大模型再叠加一个“雨夜街道”的 LoRA生成结果就会偏向特定氛围。文生图Text-to-Image是最基础的生成方式输入提示词模型从头生成整张图。它的优点是自由度高缺点是构图不好控制容易出现多余肢体、复杂场景元素丢失等问题。图生图Image-to-Image则是基于一张已有图片继续生成模型会参考原图的构图和内容再根据提示词和重绘幅度Denoising strength决定改变程度。图生图适合把草稿变成插画、把照片转换成特定风格、或者对画面做二次构成。比赛项目中常说的“XL 图生图”一般指基于 SDXLStable Diffusion XL大模型的图生图。相比 SD 1.5 系列XL 在画面细节、光影和大尺寸输出上更有优势也因此对显存和采样步数有更高要求。至于“krea2 文生图”在各类创作比赛中指代并不统一有的指的是某个在线生成工具的实时绘画能力有的只是项目内对新一代文生图模块的代号。本文不展开某一个特定云端服务的密钥配置而是从工作流结构来说明凡是提供 API 并返回图片的服务都能按同样的思路嵌入到后续链路中。2.2 LoRA 预览图系统的价值所谓“LoRA 预览图系统”并不是一个固定插件而是一种批量化、标准化的测试机制。它的核心思路是在同一底图、同一提示词、同一随机种子的前提下遍历多个 LoRA 文件或多个权重档位把生成结果排列成一张预览总图让使用者一眼看出不同 LoRA 的风格差异。这样做有三个好处。第一对照变量只有 LoRA结果可信度更高第二批量操作让人工介入最少适合比赛答辩前集中产出素材第三预览图可以直接存成比赛工作流的过程记录方便向评委展示“我们如何从多组候选模型中筛选最终方案”。2.3 工作流的分层结构整套方案可以拆成四层层级作用典型工具交互层设计者处理构图、图层、选区Photoshop桥接层把 PS 的状态发送到生成后端sd-ppp 插件或自写脚本生成层执行文生图、图生图、LoRA 叠加Stable Diffusion WebUI存储层记录模型、参数、种子、输出本地文件夹 JSON 配置四个层从下往上组合才构成一个“可复用”的工作流。缺少桥接层PS 就只是看图工具缺少存储层每次调参都靠记忆就谈不上工程化。文章后面会以 Stable Diffusion WebUI 作为生成后端来演示。如果你选择 ComfyUI也可以参考相同思路只不过 API 请求格式会不同需要按你安装的 ComfyUI 版本进行调整。3. 环境准备与基础配置3.1 工具链与版本说明文章中涉及的工具较多为了避免读者复制命令后因为版本差异失败先列出本项目中的核心工具链工具作用版本提示Photoshop原画、合成、修图建议 CC 以上版本不同版本对脚本支持有差异Stable Diffusion WebUI本地生成后端本文以 Auto1111 WebUI 为例其他 WebUI 需按接口调整Python运行批量脚本3.9 或以上需要 requests、PillowLoRA 模型文件风格或人物微调文件放入 WebUI 的 models/Lora 目录sd-ppp 插件PS 与 WebUI 之间的桥接根据插件 README 安装不同工具的大版本之间可能存在兼容性差异比如某个 Photoshop 版本不识别新版插件又如 WebUI 从 1.6 升级后 LoRA 标签的解析方式有细微变化。因此版本需要根据你的项目实际情况调整本文重点演示配置思路。3.2 WebUI 以 API 模式启动为了让 Photoshop 插件和自定义 Python 脚本能够调用 WebUI必须让 WebUI 开启 API 接口。以 Windows 环境为例进入 WebUI 安装目录后执行以下命令python launch.py --api如果你的显存小于 8GB、希望生成 XL 模型时更稳定可以追加python launch.py --api --medvram参数说明--api是必须项没有它外部程序无法访问http://127.0.0.1:7860/sdapi/...接口。--medvram表示中等显存优化适合 6GB 到 8GB 显存环境但会略微降低速度。如果你的机器配置较高可以不写--medvram。启动成功后浏览器访问http://127.0.0.1:7860能看到 WebUI 页面说明服务正常。为了验证 API 是否可用可以在浏览器单独访问http://127.0.0.1:7860/sdapi/v1/sd-models。如果返回一段 JSON 数组里面包含模型名称列表就说明 API 正常。3.3 在 Photoshop 中接入本地生成服务PS 里接入 WebUI 的常见方案是安装 sd-ppp 插件。这个插件允许你在 PS 面板中填写 WebUI 地址并把当前画布发送到生成后端。安装时注意以下几点下载插件后先关闭 Photoshop。按插件文档要求把插件目录复制到 PS 对应的扩展目录或执行安装器脚本。重新打开 Photoshop在“扩展”或“脚本”菜单中找到插件入口。在插件的 API 地址配置项中填写http://127.0.0.1:7860。如果你的 WebUI 设置了登录密码或使用了反向代理需要按插件支持的认证字段额外配置。有些 PS 版本对第三方脚本有签名限制如果插件不能正常加载通常需要在 PS 偏好设置中关闭“允许载入扩展”的相关限制或改用插件作者推荐的签名版本。建议以插件官方 README 为准。3.4 确认 LoRA 模型已就绪把要测试的 LoRA 文件放入 WebUI 的models/Lora目录。为了脚本方便建议文件名不要包含中文和空格例如rainy_street_v1.safetensors cyberpunk_costume_v3.safetensors在 WebUI 的 txt2img 页面中点击生成按钮下方的 LoRA 图标如果能看到这些文件说明模型目录配置正确。需要注意SD 1.5 训练的 LoRA 通常不能直接用于 XL 大模型反之亦然。如果你的实验对象是 XL 图生图要使用 XL 版本的 LoRA。4. 实战一批量生成 LoRA 预览图4.1 为什么固定种子和提示词LoRA 预览效果对比最怕“变量失控”。如果每一次测试都使用不同的随机种子那么两张图的差异可能来自随机噪声而不是来自 LoRA 本身的风格能力。所以在批量脚本中我们把提示词、负向提示词、采样器、步数、CFG、尺寸这些参数全部固定只改变 LoRA 标签并把随机种子固定为一个整数。同样的道理也适用于权重测试。推荐先固定一个 LoRA按 0、0.2、0.5、0.8、1.0 五档权重各生成一次确认该 LoRA 对画面影响强度再固定合适的权重横向对比多个 LoRA。这个方法成本很低非常适合比赛前期的方案筛选。4.2 批量生成脚本下面是一段可直接复制运行的 Python 脚本。脚本会遍历指定目录下的 LoRA 文件为每个 LoRA 调用 WebUI 的 txt2img 接口生成一张图并把结果拼成一张预览总图。# 文件路径scripts/lora_preview_generator.py LoRA 预览图批量生成脚本 使用前请先启动python launch.py --api import os import requests import base64 from io import BytesIO from PIL import Image, ImageDraw, ImageFont # 基础配置 API_BASE http://127.0.0.1:7860 LORA_DIR D:/models/Lora # 修改为你的 LoRA 目录 OUTPUT_DIR D:/output/lora_preview # 输出目录 BASE_MODEL sd_xl_base_1.0.safetensors # 修改为你的基础模型名称 # 用于横向对比的固定提示词请按你的主题修改 POSITIVE_PROMPT 1girl, city street at night, neon light, detailed face, masterpiece NEGATIVE_PROMPT lowres, bad anatomy, bad hands, extra fingers, jpeg artifacts, watermark # 固定参数只改变 LoRA COMMON_PARAMS { steps: 28, cfg_scale: 7.0, width: 768, height: 1024, sampler_name: DPM 2M Karras, seed: 20240817, batch_size: 1, override_settings: { sd_model_checkpoint: BASE_MODEL } } def get_lora_files(path): 读取目录下所有 safetensors 文件返回不带扩展名的文件名列表。 files [] for name in os.listdir(path): if name.endswith(.safetensors) or name.endswith(.ckpt): files.append(os.path.splitext(name)[0]) return sorted(files) def txt2img(lora_nameNone, lora_weight0.8): 调用 WebUI 的 txt2img 接口。 if lora_name: prompt flora:{lora_name}:{lora_weight}, {POSITIVE_PROMPT} else: prompt POSITIVE_PROMPT payload { prompt: prompt, negative_prompt: NEGATIVE_PREVIEW, **COMMON_PARAMS, } resp requests.post(urlf{API_BASE}/sdapi/v1/txt2img, jsonpayload, timeout180) resp.raise_for_status() return resp.json()[images][0] def save_preview_grid(image_map, output_path, columns3): 将多个 LoRA 的结果拼成网格图便于快速对比。 images [] labels [] for name, b64_img in image_map.items(): raw base64.b64decode(b64_img) img Image.open(BytesIO(raw)).convert(RGB) images.append(img) labels.append(name) cell_w max(img.width for img in images) cell_h max(img.height for img in images) 40 rows (len(images) columns - 1) // columns grid_w cell_w * min(columns, len(images)) grid_h cell_h * rows canvas Image.new(RGB, (grid_w, grid_h), white) draw ImageDraw.Draw(canvas) try: font ImageFont.truetype(arial.ttf, 18) except Exception: font ImageFont.load_default() for index, (name, img) in enumerate(zip(labels, images)): x (index % columns) * cell_w y (index // columns) * cell_h canvas.paste(img, (x, y 40)) draw.text((x 10, y 8), name, fillblack, fontfont) os.makedirs(os.path.dirname(output_path), exist_okTrue) canvas.save(output_path) print(f预览图已保存{output_path}) if __name__ __main__: # 先跑一张无 LoRA 的基线图用于确认固定提示词效果 results {baseline_no_lora: txt2img(lora_nameNone)} # 再遍历所有 LoRA for lora in get_lora_files(LORA_DIR): print(f正在生成 LoRA{lora}) image_b64 txt2img(lora_namelora, lora_weight0.8) results[lora] image_b64 output_file os.path.join(OUTPUT_DIR, lora_preview_grid.png) save_preview_grid(results, output_file)代码里有几个容易出错的地方需要说明。POSITIVE_PROMPT和NEGATIVE_PROMPT分开写是为了保证不同 LoRA 只改变画面风格不改变画面主体描述。脚本底部先跑一张baseline_no_lora没有叠加任何 LoRA这样你可以对比“没加 LoRA”和“加了 LoRA”之间的差异。override_settings里需要填 WebUI 可用的大模型名称。你可以先访问http://127.0.0.1:7860/sdapi/v1/sd-models从返回结果中复制完整的模型文件名。4.3 运行与结果阅读假设你已经把脚本放在scripts目录下先安装依赖pip install requests pillow然后运行python scripts/lora_preview_generator.py如果一切正常终端会循环打印正在生成 LoRArainy_street_v1 正在生成 LoRAcyberpunk_costume_v3 预览图已保存D:/output/lora_preview/lora_preview_grid.png打开输出的网格图后你应该能快速完成两个判断第一哪些 LoRA 风格符合项目设定第二哪些 LoRA 会明显破坏面部或结构。前者决定建模方向是否走通后者决定要不要检查该 LoRA 的基础模型是否匹配。如果你希望在 Photoshop 里直接查看这些预览图可以将网格图作为参考图层放入画布生成正式输出后把预览图层关闭。这样能保留“先选型、后产出”的决策记录。5. 实战二XL 图生图与局部重绘流程5.1 XL 图生图的典型使用场景参赛作品通常包含大量原画草稿。草稿有明确的构图和线条但缺少颜色、光影和材质细节。此时如果直接走文生图模型大概率会自由发挥构图容易跑偏。使用 XL 图生图可以让模型在尊重草稿结构的前提下补全画面。在 PS 中的常见流程是将草稿或线稿整理到单独图层。用选区或蒙版圈出要重绘的区域。把当前可见图层发送给生成端执行图生图。设置合理的重绘幅度一般 0.35 到 0.55 比较合适。生成结果返回后利用 PS 蒙版把满意的部分保留下来不满意的区域再继续迭代。需要注意的是无论是 XL 图生图还是局部重绘都不是“一键自动完成”的魔术。你需要先把画面中不想要的部分用 PS 工具清理掉因为图生图会保留原图中的大量信息。如果原图里有明显的文字水印生成结果也会很难彻底去除。5.2 通过 API 发起图生图很多 PS 插件已经内置了图生图按钮你可以直接使用插件面板操作。但如果是参赛演示我建议额外保留一段脚本作为兜底方案方便处理批量素材或自动记录参数。# 文件路径scripts/img2img_bridge.py 从本地图发送图生图请求适合与 PS 导出文件配合使用。 实际使用中PS 插件可以把当前画布直接发送到该接口。 import requests import base64 import json API_BASE http://127.0.0.1:7860 BASE_MODEL sd_xl_base_1.0.safetensors # 可按需替换 # 图片文件路径 SOURCE_IMAGE D:/work/ps_export/sketch.png # 是否启用局部蒙版不需要时可以留空 MASK_IMAGE D:/work/ps_export/mask.png with open(SOURCE_IMAGE, rb) as f: source_b64 base64.b64encode(f.read()).decode(utf-8) payload { init_images: [source_b64], prompt: detailed digital painting, cinematic lighting, masterpiece, best quality, negative_prompt: lowres, bad anatomy, bad hands, blurry, steps: 30, cfg_scale: 6.5, width: 1024, height: 1024, denoising_strength: 0.45, sampler_name: DPM 2M Karras, seed: -1, override_settings: { sd_model_checkpoint: BASE_MODEL } } if MASK_IMAGE: with open(MASK_IMAGE, rb) as f: mask_b64 base64.b64encode(f.read()).decode(utf-8) payload[mask] mask_b64 resp requests.post( urlf{API_BASE}/sdapi/v1/img2img, jsonpayload, timeout180 ) resp.raise_for_status() result resp.json() # 保存生成结果 with open(D:/work/ps_export/result.png, wb) as f: f.write(base64.b64decode(result[images][0])) print(图生图完成结果已保存到 result.png) print(本次使用的种子是, result.get(info))上面代码涉及两个需要强调的参数。denoising_strength表示重绘幅度数值越大改变越多如果是草图风格转到成品插画0.45 左右可以保留构图但补充细节如果只是想局部换一个配色可以降到 0.2 到 0.3。如果传入mask字段模型只会在蒙版白色区域重绘这种方式对应 PS 里的局部重绘。5.3 在 sd-ppp 中手动执行的路线如果你的重点是快速验证不一定要跑代码。使用 sd-ppp 插件的常规操作如下在 PS 中框选需要处理的区域或直接选中图层。在插件面板中切换模式到 img2img。把画布内容作为 init image 发送确认目标尺寸。在提示词中输入要优化的内容并调整 denoising 强度。点击生成等待结果回到新图层然后手动混合。如果你使用了局部选区建议把选区保存为通道或者蒙版。有些 PS 插件支持自动读取当前选区有些则不支持需要看你具体安装的版本。6. 实战三文生图模块与 krea2 类能力的接入6.1 文生图在整个流程里的位置文生图并非和 Photoshop 二选一。更合理的组织方式是先用文生图做脑暴产生多张构图方向再把其中最有价值的构图导入 PS最后通过图生图细化。这样做可以避免一上来就被 PS 里的空白画布限制住灵感。在参赛工作流中“krea2 文生图”可以理解为一个提供高自由度的灵感生成模块。由于这类在线服务的 API 协议并不统一且不同比赛版本所指向的服务也经常变化我这里不给某一家云端服务的具体账号接入步骤而是提供一个稳定接入原则把服务封装成统一函数入参是提示词和图片尺寸返回值是图片字节流或文件路径。这样即使更换服务商上层提示词模板和 PS 集成逻辑都不用重写。如果你希望在本地获得更好的文生图体验也可以直接用第 4 节里的 txt2img 接口只是不叠加 LoRA而是把提示词空出来专门做灵感探索。6.2 搭建提示词模板管理文生图最耗时的地方不是点击生成而是写提示词。在 PS 工作流中可以把常用提示词做成一个文本模板主题{subject} 场景{scene} 光线{lighting} 镜头{shot} 风格{style} 负面{negative_words}然后通过脚本的配置文件把模板参数映射到实际调用中。后期如果想加入 LoRA再在正向提示词开头追加lora:模型名:权重即可。这样的模板化结构让比赛过程中的每次实验都可记录、可重现而不是靠灵感碰运气。配置文件示例{ subject: a futuristic girl detective, scene: rainy cyberpunk street, lighting: neon rim light, shot: medium shot, style: detailed anime style, negative_words: lowres, bad anatomy, bad hands }6.3 快速验证接口是否可用的建议如果你要接入一个非本地、非标准 API 的在线文生图服务先不要急着开发整套 UI先用一段最小脚本验证三个问题服务是否支持 API key 认证key 应该放在环境变量而不是源码中。服务返回内容是图片 URL 还是 base64以及是否有异步任务队列。服务对图片尺寸、格式、内容审核有哪些限制。验证通过后再考虑和 PS 的联动。如果某家服务的访问经常超时或者返回结果不稳定不建议把它放在主流程里可以把它作为审美参考通道而不是生产通道。7. 常见报错与排查清单工作流一旦串起来最考验人的往往是排错能力。以下列表总结了本项目里最容易踩中的几类问题。问题现象常见原因解决思路PS 插件无法连接 WebUIWebUI 没启动或没加--api参数重启 WebUI访问 API 地址确认可返回 JSON调用接口报 500 错误提示词或 LoRA 标签格式错误模型文件被占用到 WebUI 页面手动生成一次查看控制台报错图生图结果和原图差太多denoising_strength过高降到 0.3-0.55 再试LoRA 几乎不起作用LoRA 基础模型与当前大模型不匹配确认 SD1.5 LoRA 不能直接配合 XL 基础模型使用LoRA 效果过于夸张LoRA 权重过高先降到 0.5 以下或调整提示词中的触发词生成后没有画面返回WebUI 卡死或超时检查显存占用重启 WebUI提高脚本 timeoutXL 生成特别慢显存不足或没有使用对应优化参数尝试--medvram降低分辨率或缩小 batch size预览窗口看不到图插件配置的图片回传地址错误确认插件配置和 WebUI 地址一致检查网络端口如果你在 ComfyUI 中生成图片遇到“在预览窗口看不到预览图但实际已生成”的问题通常也是节点预览组件和输出节点的设置不一致导致的。可以先到 ComfyUI 的输出目录查看 PNG 文件是否已经落盘确认生成成功后再排查前端预览配置。在本地调试阶段建议优先开一个独立的 WebUI 控制台窗口出现报错时不要只看浏览器网络面板因为 Python 进程的控制台会输出更详细的后端异常信息。8. 最佳实践与工程级建议从“能跑到”到“能手把手给别人演示”中间还差工程化这一步。这里分享几条对参赛或项目落地都有帮助的经验。第一所有生成参数都要有记录。不要只保存图片建议把提示词、负向提示词、采样器、步数、CFG、种子、LoRA 文件名、LoRA 权重一起存成 JSON 或 CSV。日后想要复现某个效果有记录才能复现否则比赛答辩时被问到“这张图怎么生成”只能支支吾吾。第二统一 LoRA 命名规范。例如按日期_风格_版本来命名20250115_rainy_street_v1.safetensors这样做的好处是批量脚本的输出网格能够按文件名排列从输出图片上就可以看出版本迭代关系。第三使用自有的或已授权素材进行测试和参赛。比赛中如果用他人照片或未授权原画做图生图底稿既可能违反比赛规则也有版权风险。建议在流程设计阶段就使用自己的手绘草稿、原创摄影或开源协议允许的测试图片。第四提示词库里尽量只保留对结果有确定性影响的词。不要在一句话里堆十几个风格形容词否则你很难判断最终效果到底来自哪个词更没法解释给评委听。把提示词拆成“主体 场景 光效 风格 负面”五段定位问题会容易很多。第五不要让 AI 生成流程脱离人工审核。无论使用本地模型还是在线服务都要遵守模型使用条款不能生成违法、违规或不符合公序良俗的内容。这一点在公开比赛场景中尤其重要作品的主题和训练数据来源必须经得起核查。第六对显存资源做预算。XL 图生图比文生图更吃显存因为除了模型参数外还要加载输入图片。批量预览时不要让脚本一次发多个并发请求否则显存瞬间溢出轻则报错重则导致 WebUI 假死。建议在脚本里加一个sleep或使用信号量控制并发数。第七分类保存输出目录。建议至少分成三个目录raw存放模型原始输出ps_retouch存放 PS 修图后的结果final存放最终参赛展示图。原始输出被误修改后至少还能通过备份找回。这里我想多说一句关于安全边界的建议本机服务默认监听 127.0.0.1 时只有本机能访问。如果你为了让其他电脑访问而把监听地址改成 0.0.0.0至少要确认自己所在的网络环境可信并且要在服务端做身份认证。在未配置认证的情况下把模型服务暴露到局域网或公网极容易被其他人调用造成 GPU 资源耗尽甚至被滥用生成不当内容。比赛演示时如果必须联网建议只在可信的演示网络内临时开启演示结束立刻关闭。9. 后续可以继续深入的方向如果上面的基础流程你已经跑通下一步并不是继续增加更多 LoRA 文件而是围绕“可控性”做深化。你可以尝试把 ComfyUI 作为生成后端用节点方式把 LoRA、图生图、局部重绘连接成固定模板这样每次执行顺序完全一致参数调整也更容易可视化。也可以尝试在 PS 端记录每一步图层的生成数据把整张作品的创作过程保存为一种“可回放的工作流”这在 AI 创作类比赛中通常是很加分的展示形式。你还可以给脚本增加一个简单的 UI 或批次清单文件每次只需修改 JSON 配置就能切换不同提示词模板、不同 LoRA 权重表而不需要改代码逻辑。如果你想研究得更深不妨从 LoRA 训练反推命名和管理规范或者为自己的常用风格训练一组专用 LoRA再回过来接入这套 Photoshop 预览系统。技术方案是否优秀不取决于单个模型有多强而取决于它能不能稳定嵌入到创作者的真实工作习惯里。Photoshop、LoRA、WebUI、API 脚本这些组件单独拿出来都算不上新东西把它们按“预览—生成—精修—沉淀”的节奏组合起来才真正构成一套属于自己的 AI 绘画工作流。希望本文的工程细节和排错经验能帮你在比赛或实际项目中少走一段弯路。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门