☰
本地AI批量生成随机卡牌图像:Stable Diffusion提示词与种子控制实战
2026/10/16 9:43:07 网站建设 项目流程

如果给一个叫“安东尼”的人一套本地 AI 生成环境,他会怎么用算法造出一批“随机假卡”?这篇文章就来拆这个事。这里的“假卡”不是拿来伪造球星卡、交易卡或任何实体卡牌,而是用算法批量生成卡牌样图,跑一个可以复制的“随机造卡流水线”。标题里的“储君篇”可以理解为这个系列里偏模板化、偏批量化的一个篇章——你不需要懂太多美术,只需要把提示词、随机种子、固定模板和接口服务串起来,就能得到一整组风格统一、元素随机的卡面图。

先把结论放前面:这个流程的核心是四个模块——随机提示词组合、统一卡面模板、批量 API 生成、自动排版导出。只要能跑通 Stable Diffusion WebUI 或 ComfyUI 的本地 API 服务,再用一段 Python 脚本控制随机种子和参数,剩下的就是批量出图和整理目录的事。下面会完整演示环境准备、启动方式、接口调用、批量任务和常见坑。想直接抄作业的,可以重点看第 4 节到第 6 节。

1. 随机假卡生成流水线:核心能力速览

能力项说明
项目类型本地 AI 图像批量生成 + 卡面排版自动化
技术核心Stable Diffusion 系列模型、随机种子控制、提示词模板组合、Pillow 图文排版
主要功能随机生成卡牌底图、统一卡牌版式、批量导出 PNG、支持接口调用
硬件门槛有 NVIDIA 显卡的 Windows / Linux 机器最合适;具体显存需求需按模型版本测试,没有显卡也可以用纯 CPU 跑但速度会明显偏慢
显存占用取决于模型、分辨率、批大小;本文不写死具体数字,第 7 节会给观察方法
支持平台Windows / Linux / macOS(macOS 依赖实际情况,N 卡兼容性更好)
启动方式命令行启动 WebUI 或 ComfyUI API 服务,再用本地脚本提交任务
是否支持 API支持,可调用本地 HTTP 接口批量提交生成任务
是否支持批量任务支持,建议把提示词、种子、输出路径全部写在 JSON 配置里,按队列循环生成
适合场景个人收藏卡样图、虚拟实体卡设计预研、桌游角色卡原型、自动化素材生产
不适合场景伪造真实球星卡 / 交易卡、未授权使用真实球员或真人肖像、任何以假乱真的商业行为

这套流水线本质上不复杂,一句话概括:用“随机提示词 + 随机种子”控制 AI 画面的多样性,再用“固定模板 + 自动排版”控制成品的一致性。

2. 适用场景与使用边界

先讲适合谁。如果你手头有几千张统一的卡面需求,比如桌游卡、虚拟收藏卡、训练用样本卡,人工一张张用在线工具生成会疯掉的。适合本地算法批量生成。如果你需要“看起来是同系列但每张都不同”的效果,这套随机组合机制正好对路。抛开娱乐语境,它也是一个很好的 AI 批处理工程演示:本地 API、JSON 配置、批量循环、失败日志、结果去重,这些组合起来就是一个小型生成管线。

再讲不适合什么。不适合用来做真实球星卡的“假卡”。真实球星卡涉及肖像权、商标、球队标识、联盟授权,AI 生成图不能解决版权问题。哪怕只是自己收藏,只要涉及真实球员姓名和照片,也会踩肖像权边界。第二个不适合的场景是拿它去伪造稀有卡、欺骗其他收藏者,这不仅仅是合规问题,还可能涉及法律风险。还有一类不适合:如果只是想快速得到一张效果惊艳的封面图,不需要批量,那没必要套这套流水线,直接开 WebUI 手写提示词更快。

安全边界必须划清楚:

  • 生成卡面素材时,优先使用无版权人物、虚拟形象、自绘素材或已获授权的素材库。
  • 不要用真实公众人物姓名生成可被误解为官方卡牌的内容。
  • 不要把 AI 生成卡片挂到二手平台或交易渠道冒充实体卡。
  • 涉及批量生成的素材,建议在输出图片右下角加“AI Demo / Not Official”水印,便于和真实卡区分。

3. 随机造卡本地部署:环境准备与前置条件

下面给一套通用检查清单。具体版本以你安装模型的说明为准,不要把下面写法直接当成唯一答案。

3.1 操作系统与硬件

  • 操作系统:Windows 10/11、Ubuntu 20.04/22.04 都可以。
  • GPU:NVIDIA 显卡优先,显存越大越稳。没有材料的支持结论,建议至少从 6GB 显存开始测,实际能不能跑取决于模型选择和参数。
  • CPU 模式:可以跑,但出图速度会慢很多,适合功能验证,不适合批量。
  • 磁盘空间:至少要预留 30GB 以上。Stable Diffusion 模型文件本身就有几个 GB,再加上出图结果、Python 依赖和日志,空间很快会被吃掉。

3.2 基础软件

需要安装:

  • Python 3.10 / 3.11。
  • Git。
  • NVIDIA 显卡驱动 + CUDA 环境。具体版本看 PyTorch 要求。
  • Stable Diffusion WebUI 或 ComfyUI。二者都能提供 HTTP API,二选一即可。
  • Pillow、requests 等 Python 库,用于排版和接口调用。

3.3 前置检查命令

python --version git --version nvidia-smi

nvidia-smi能显示驱动版本和显存总量。如果命令找不到,说明驱动没装好,先去装驱动。PyTorch 是否能用 GPU,可以用下面命令快速验证:

python -c "import torch; print(torch.cuda.is_available())"

输出True代表 GPU 可用,输出False就说明 CUDA 版本或 PyTorch 安装有问题。这个检查点解决了,后面启动 WebUI 才不容易卡在设备识别环节。

4. 一键启动与本地 API 服务

这里以 Stable Diffusion WebUI 为例,因为它的 HTTP API 最直白。ComfyUI 的流程类似,只是 API 格式不同,会在第 6 节给出对应说明。

4.1 克隆并安装 WebUI

git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git cd stable-diffusion-webui

Windows 下一般直接运行webui-user.bat,Linux 下运行:

bash webui.sh

第一次启动会下载依赖并加载模型,时间比较长。模型文件需要放在models/Stable-diffusion/目录下,文件名随意,WebUI 会按模型名识别。

4.2 以 API 模式启动

WebUI 默认启动会同时打开 Web 页面和 API 服务。为了让批量任务更稳定,建议手动指定监听地址和端口:

# Linux 示例,实际启动脚本路径以你的安装目录为准 cd stable-diffusion-webui python launch.py --api --listen 127.0.0.1 --port 7860

Windows 可以在webui-user.bat里加环境变量:

set COMMANDLINE_ARGS=--api --listen 127.0.0.1 --port 7860

启动成功后,终端会显示本地访问地址。如果只在本机调用,建议--listen 127.0.0.1,不要直接暴露到公网。

4.3 验证服务是否可用

浏览器打开http://127.0.0.1:7860/sdapi/v1/txt2img,如果返回 405 或 404 属正常现象,因为该接口只接受 POST。更好的验证方式是看根路径能否打开:

curl -s http://127.0.0.1:7860/ | head -20

也可以直接请求http://127.0.0.1:7860/sdapi/v1/options获取当前配置。能返回 JSON,说明服务已经正常起来了。

5. 功能测试与效果验证

造卡流水线建议按四步测试:单张随机卡、提示词组合、批量生成、自动排版。

5.1 随机种子单卡测试

测试目的:确认本地服务能出图,并且随机种子确实能改变画面。

先用 WebUI 页面手动填一个提示词,比如:

card game illustration, fantasy character portrait, glowing runes, strong contrast, high detail

负面提示词填:

lowres, bad anatomy, watermark, text, blurry, jpeg artifacts

把Seed设为-1代表每次随机,点击生成。如果页面能出图,说明基础链路没问题。

接着测试种子稳定性:把同一提示词分别用 Seed 1、Seed 2、Seed 3 各生成一张,对比卡面元素差异。这一步决定了后面批量生成好不好用。如果种子变化不明显,检查是不是“高清修复”或“变体”功能干扰了随机性。

5.2 提示词组合测试

随机假卡的重点是“随机”,但随机不能变成全乱。建议使用角色 + 背景 + 风格 + 稀有度四段式模板:

模板位置可替换词
角色战士 / 法师 / 游侠 / 龙裔 / 机械守卫
背景地牢 / 雪原 / 浮空岛 / 遗迹 / 星港
风格油画风 / 日系平涂 / 赛博朋克 / 水墨风
稀有度普通铜框卡 / 稀有银框卡 / 史诗金框卡

用 Python 按随机权重组合提示词,再提交给 API。注意风格词不要混太多,否则容易串风格。建议每张卡只保留一种主风格词。

5.3 批量生成测试

写一个 Python 脚本循环请求/sdapi/v1/txt2img,每张图使用独立随机种子,并把参数记录到 JSON,方便追踪。

import requests import random import base64 import io from PIL import Image import os api_url = "http://127.0.0.1:7860/sdapi/v1/txt2img" characters = ["warrior", "mage", "ranger", "dragonkin"] backgrounds = ["dungeon", "snowfield", "floating island", "ruins"] styles = ["oil painting style", "japanese anime style", "cyberpunk style", "ink painting style"] rarities = ["common", "rare", "epic"] output_dir = "./generated_cards" os.makedirs(output_dir, exist_ok=True) for i in range(20): char = random.choice(characters) bg = random.choice(backgrounds) style = random.choice(styles) rarity = random.choice(rarities) prompt = f"{char}, {bg}, {style}, card game illustration, high detail" seed = random.randint(1, 999999999) payload = { "prompt": prompt, "negative_prompt": "lowres, bad anatomy, watermark, text, blurry, jpeg artifacts", "seed": seed, "steps": 30, "width": 768, "height": 1024, "cfg_scale": 7, "sampler_name": "DPM++ 2M Karras", "batch_size": 1 } resp = requests.post(api_url, json=payload, timeout=300) data = resp.json() if "images" in data: img_data = base64.b64decode(data["images"][0]) img = Image.open(io.BytesIO(img_data)) # 保存底图,命名规则:序号_稀有度_角色.png file_name = f"{i+1:03d}_{rarity}_{char}.png" img.save(os.path.join(output_dir, file_name)) print(f"[OK] {file_name} seed={seed}") else: print(f"[FAIL] {i+1} error: {data}")

脚本跑完后,检查generated_cards目录。判断成功的标准:20 张图全部能保存,图片尺寸正确,人眼可见的风格差异明显,没有大面积黑图或纯色图。

失败时优先排查三类问题:

  • 请求超时:timeout=300不够就再加,或者把steps调低。
  • 返回 500:看 WebUI 终端日志,通常是显存不足或提示词包含不支持的 token。
  • 输出全是同一个风格:检查随机种子是否真的传入,有时候请求里 seed 写死会导致所有图一样。

5.4 自动排版输出

底图生成后,还需要把卡牌文字信息压到图上。这里用 Pillow 做一层简单排版。先准备文本字段:稀有度、卡名、序号、编号。

from PIL import Image, ImageDraw, ImageFont import os card_dir = "./generated_cards" output_dir = "./cards_with_text" os.makedirs(output_dir, exist_ok=True) try: font_large = ImageFont.truetype("arial.ttf", 56) font_small = ImageFont.truetype("arial.ttf", 36) except IOError: font_large = ImageFont.load_default() font_small = ImageFont.load_default() for file_name in os.listdir(card_dir): if not file_name.endswith(".png"): continue parts = file_name.replace(".png", "").split("_") # 文件命名示例:001_epic_warrior.png uid = parts[0] rarity = parts[1] name = parts[2] img = Image.open(os.path.join(card_dir, file_name)).convert("RGB") draw = ImageDraw.Draw(img) # 底部压一条半透明黑带,提高文字可读性 overlay = Image.new("RGBA", img.size, (0, 0, 0, 0)) od = ImageDraw.Draw(overlay) od.rectangle([0, img.height - 160, img.width, img.height], fill=(0, 0, 0, 160)) img = img.convert("RGBA") img = Image.alpha_composite(img, overlay).convert("RGB") draw = ImageDraw.Draw(img) draw.text((60, img.height - 150), f"{rarity.upper()} - {name.title()}", fill=(255, 255, 255), font=font_large) draw.text((60, img.height - 80), f"NO.{uid}", fill=(200, 200, 200), font=font_small) img.save(os.path.join(output_dir, file_name)) print(f"[SAVE] {output_dir}/{file_name}")

这段脚本会在卡片底部生成半透明信息栏。如果文字溢出,把字号调小或加长底部色带高度。排版完成后的图,可以直接用于预览、归档或文档展示,但不能直接视为“可流通实体卡设计成品”,因为还差版权审核和印刷标准。

6. 接口 API 与批量任务设计

6.1 WebUI API 请求格式

WebUI 的/sdapi/v1/txt2img是最常用的接口。返回 JSON 里images是 base64 编码的图片列表。需要注意,batch_size和n_iter同时控制输出数量:

  • batch_size:每次生成几张图。
  • n_iter:循环几轮。

如果你的显存不充裕,建议保持batch_size=1,通过外部 Python 循环控制数量。否则显存峰值容易突然拉高。

6.2 批量任务队列设计

批量任务不能光写个for循环。更稳妥的结构是:先用 JSON 配置任务清单,再写执行器读取配置并逐条处理。

{ "base_dir": "./generated_cards", "output_dir": "./cards_with_text", "tasks": [ { "id": "001", "rarity": "epic", "character": "warrior", "background": "dungeon", "style": "oil painting style", "seed": 123456 }, { "id": "002", "rarity": "rare", "character": "mage", "background": "floating island", "style": "japanese anime style", "seed": 654321 } ] }

执行器读取tasks列表,把每个任务拼成提示词,提交 API,保存图片,并把状态写入日志。这样如果跑到第 15 张失败,重启脚本后可以跳过已完成任务,不用从头再来。

6.3 失败重试与状态记录

批量任务里最常见的坑是:某一张图超时,整个队列中断。建议给每次请求加 5 分钟超时,并对失败任务做 3 次重试:

for attempt in range(3): try: resp = requests.post(api_url, json=payload, timeout=300) if resp.status_code == 200: break except requests.exceptions.Timeout: print(f"task {task_id} timeout, retry {attempt + 1}")

每次生成完成后,把task_id、seed、prompt、输出文件名、耗时写到logs.csv。遇到效果不好的图,至少能知道是哪一组随机参数导致的。

6.4 ComfyUI API 说明

ComfyUI 也可以做批量生成,但它的 API 格式和 WebUI 不一样。ComfyUI 的 API 是一整个workflowJSON,里面定义了节点连接关系,调用方式通常是:

import json import urllib.request workflow_path = "workflow_api.json" with open(workflow_path, "r", encoding="utf-8") as f: workflow = json.load(f) # 这里需要根据当前节点 id 修改 prompt 和 seed # 具体字段名以 ComfyUI 导出的 workflow 为准 data = json.dumps({"prompt": workflow}).encode("utf-8") req = urllib.request.Request("http://127.0.0.1:8188/prompt", data=data, headers={"Content-Type": "application/json"}) resp = urllib.request.urlopen(req, timeout=300) print(resp.read().decode("utf-8"))

所以如果你是要做“可复制造卡流水线”,我建议优先用 WebUI 的/sdapi/v1/txt2img,因为参数更扁平、更容易做批量循环。ComfyUI 胜在节点灵活,但要把工作流导出成 API 格式,上手成本高一些。

7. 资源占用与性能观察方法

这节不写死任何具体显存数字,因为不同模型、不同分辨率、不同采样步数差异太大了。下面讲怎么观察和调优。

7.1 显存占用怎么观察

生成图片时,另开一个终端,用nvidia-smi查看进程显存:

nvidia-smi -l 1

-l 1表示每秒刷新一次。重点看/stable-diffusion-webui 或 python进程对应显存占用。启动 WebUI 后显存就占一部分,生成时会再加一层峰值。观察时不要只看瞬时数字,要盯住生成过程中的最高值。

7.2 哪些参数影响最大

从常见实践看,影响排列大致是:

  • 分辨率:1024x1024 比 768x1024 更吃显存,等比调大会明显拉高峰值。
  • 采样步数:步数越高耗时越长,显存增量小于分辨率影响,但会拖慢批量速度。
  • 批量大小:batch_size从 1 调到 2,显存几乎接近翻倍,风险很高。
  • 模型版本:SD 1.5、SDXL、Pony、Illustrious 等不同模型,底层结构和文本编码器不同,显存占用差异很大。
  • 高清修复:hires fix会先把低分辨率图生成,再放大,放大阶段显存占用会二次升高。

7.3 如何降低显存占用

  • 保持batch_size=1,用循环代替并行。
  • 分辨率从 640x832 起步,不要一上来就跑 1024。
  • 开启 WebUI 的medvram或lowvram启动参数,会限制显存策略。
  • 关掉多余插件,部分预览类插件也会吃显存。
  • 如果显存不足导致黑图,优先降低分辨率,而不是降步数。

7.4 CPU 推理是什么体验

没有独显时,SD 出图只能靠 CPU 硬算,单张 768x1024 图可能耗时几十秒到几分钟。功能验证可以,批量任务不建议。如果你必须用 CPU,把steps调到 18 到 20,分辨率降到 512x768,先确认输出质量,再考虑数量。

7.5 端口和进程管理

WebUI 默认端口是 7860,ComfyUI 默认是 8188。如果端口被占,启动会提示 address already in use。处理方式:

# 查看端口占用 netstat -ano | grep 7860 # Linux 杀进程 kill -9 <PID>

Windows 用资源管理器或:

netstat -ano | findstr 7860 taskkill /PID <PID> /F

批量任务跑完后,服务进程不会自动退出,需要手动关。长时间挂机生成时建议设置输出目录按日期分目录,避免文件散落。

8. 随机假卡生成常见问题与排查方法

问题现象可能原因排查方式解决方案
启动后页面打不开服务未完全启动、端口被占用或防火墙拦截查看启动日志、检查端口换端口重启,或关闭防火墙限制
生成的黑图或纯色图显存不足、提示词冲突、步数太低查看终端报错、降低分辨率降低分辨率或步数,关掉高清修复
所有卡片画面高度相似随机种子没有生效、提示词模板过于单一检查请求参数里的 seed 字段每次调用显式传随机种子,扩宽词库
批量生成中途卡住某次请求超时或接口无响应看日志停在哪个任务增加 timeout,添加失败重试和断点续跑
生成的图片有乱码文字模型直接画了文字但效果不可控检查负面提示词已有 text优先后期排版加文字,不要依赖 AI 出字
调用 API 返回 500模型加载失败、参数字段写错看 WebUI 终端堆栈核对请求字段名,确认模型文件已放到目录
显存不足导致崩溃单图分辨率过高或 batch_size 过大观察 nvidia-smi 峰值调低分辨率,batch_size 保持 1
出图风格混搭风格词叠加太多检查提示词模板每张卡只保留一个主风格词
本地 API 被外部访问启动时用了--listen 0.0.0.0且无访问限制检查监听地址改回127.0.0.1,或加访问密钥
输出的卡面缺少真实卡质感缺少边框、底纹、文字排版看底图与成品卡差别用 Pillow 补框线、稀有度背板、编号条

排查的基本原则很简单:先看终端日志,再看请求参数,最后看显存和磁盘。如果是批量任务,不要一次性跑 100 张,先跑 5 张确认参数稳定,再扩量。

9. 最佳实践与使用建议

把这套流水线当工程来做,而不是当“抽卡娱乐”来做,有几个建议很实用。

第一,第一次只跑小参数。比如先用steps=20、width=768、height=1024、batch_size=1跑 5 张,确认没有黑图和显存崩溃,再慢慢加数量和分辨率。不要一上来就 50 张,不然中途炸了很难定位问题。

第二,把输入词库、配置文件和输出目录分开。词库存成 Python 列表,配置文件存成 JSON,输出目录按日期或任务号命名。这样每次生成的参数、种子、prompt 都能追踪。用一段logs.csv记录每次成功图片的种子和提示词,比到时候翻截图靠谱得多。

第三,加“去重”意识。随机种子虽然能保证画面不同,但相近提示词 + 相近种子可能会出非常相似的图。批量生成后,可以按文件大小和图片哈希粗筛一遍:

# Linux/macOS 下按 md5 找重复图 find ./generated_cards -name "*.png" -exec md5sum {} \; | sort | uniq -w32 -d

Windows 可以用 Python 计算哈希。重复图要么删掉,要么把提示词模板里的角色词、背景词再多扩一倍。

第四,生成结束后要做人工抽查。算法不会判断“这张卡面侵权”或“这个文字排版歪了”。如果你要对外展示,需要有人眼审核环节。批量任务跑完不等于成品可用。

第五,接口服务注意访问边界。本地 API 不要轻易绑定0.0.0.0。如果真要同一局域网内调试,也要清楚别人访问你的 7860 端口就能直接生成图片,风险自负。最稳妥的是只用127.0.0.1,同一脚本在服务器本机跑。

第六,涉及人物、品牌、队徽、真实名称时,先确认授权。你要生成的是“随机假卡”,就不要用真人真名。建议在系统提示词里要求产出虚拟角色名,比如用“mage”代替“某个明星球员”。

第七,发布或商用前做效果复核。AI 生成卡面往往会出现手指、文字拼写、边缘瑕疵。缩略图看着还行,放大看可能完全不能看。如果用于正式产品,建议先做超分和二次修图,必要时人工润色。

10. 总结与下一步

回到“假如安东尼使用算法生成随机假卡”这个场景。用这套流程,你只需要有一台能跑 Stable Diffusion 的机器,装好 WebUI,把提示词模板、随机种子、批量脚本、排版脚本串起来,就能批量得到一批风格统一但内容随机的卡面图。最值得试的是随机种子 + 四段式提示词组合的玩法,它性价比最高,改动小,出图差异明显。

最容易踩的坑有三个:一是没有先跑小批量就开大流程,导致显存或超时问题把整个队列打断;二是随机种子没有真正传进去,结果 50 张图全是一个模子;三是忘了做合规边界检查,把包含真实人物姓名或受版权保护标识的内容放进批量任务。先跑通 5 张,再扩展词库,再加大批量,是性价比最高的路径。

后续可以继续扩展的方向包括:把 HTML 文本模板改成 SVG 排版,做更精细的卡牌 UI;接入微信机器人或 Web 服务,让用户输入关键词就随机发卡;加入人脸一致性方案生成系列角色卡;甚至把输出结果接入自动化存档系统,按稀有度自动归档。每一个方向都可以单独再写一篇,核心底座就是本文这条生成 + 排版 + 批量的流水线。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询