基于 Python 实现 FLUX.1-dev 图像生成 API 的自动化批量处理
技术背景与应用场景
FLUX.1-dev 作为当前高质量的图像生成模型,虽然提供了直观的 WebUI 界面,但在面对大批量素材生产、参数对比测试或自动化工作流集成时,手动点击的操作方式效率较低。通过 Python 脚本直接调用其背后的 Flask API,可以实现图像生成的工程化管理,极而提高产出效率并确保生成参数的可追溯性。
开发环境准备
在编写自动化脚本前,需要确保本地 Python 环境已安装必要的通信与图像处理库。主要的依赖包括用于发送 HTTP 请求的 requests 和处理图像文件的 Pillow。
pip install requests Pillow
通常,FLUX.1-dev 部署后的 API 接口遵循标准的 RESTful 规范,接受 JSON 格式的 POST 请求。常见的参数项包括提示词 (prompt)、采样步数 (steps)、引导系数 (guidance/cfg_scale) 以及分辨率等。
核心客户端类实现
为了提高代码的复用性,我们封装一个 FluxImageService 类。该类负责管理 API 端点配置,并处理与服务器的通信逻辑。代码中加入了对 Base64 编码和二进制流两种常见响应格式的处理逻辑。
import requests
import os
import io
import time
import base64
from PIL import Image
class FluxImageService:
def __init__(self, endpoint_url="http://127.0.0.1:7860/api/generate"):
self.url = endpoint_url
def _process_response(self, response, target_path):
"""解析响应内容并保存图像"""
if response.status_code != 200:
print(f"请求失败,状态码: {response.status_code}")
return False
try:
# 兼容处理:某些 API 返回 JSON 包含 base64,某些直接返回二进制流
content_type = response.headers.get('Content-Type', '')
if 'application/json' in content_type:
data = response.json()
img_b64 = data.get('image') or data.get('images', [None])[0]
img_data = base64.b64decode(img_b64)
else:
img_data = response.content
img = Image.open(io.BytesIO(img_data))
img.save(target_path)
return True
except Exception as e:
print(f"图像解析异常: {e}")
return False
def fetch_image(self, text_prompt, output_name, **config):
"""执行单次生成请求"""
payload = {
"prompt": text_prompt,
"steps": config.get("steps", 20),
"guidance": config.get("guidance", 3.5),
"width": config.get("width", 1024),
"height": config.get("height", 1024),
"seed": config.get("seed", -1)
}
print(f"正在处理提示词: {text_prompt[:30]}...")
start_ts = time.time()
try:
resp = requests.post(self.url, json=payload, timeout=120)
success = self._process_response(resp, output_name)
if success:
print(f"生成成功,耗时: {time.time() - start_ts:.1f}s")
return output_name
except requests.RequestException as err:
print(f"网络请求错误: {err}")
return None
批量任务自动化逻辑
批量处理的核心在于任务队列的遍历以及文件命名冲突的处理。我们可以定义一个任务执行器,支持从列表或配置文件中读取多个提示词,并自动建立输出目录。
def run_batch_tasks(service, task_list, save_dir="outputs"):
if not os.path.exists(save_dir):
os.makedirs(save_dir)
results_log = []
for idx, task in enumerate(task_list):
# 允许任务列表包含字符串或字典
prompt = task["text"] if isinstance(task, dict) else task
filename = f"gen_{idx:04d}.png"
save_path = os.path.join(save_dir, filename)
# 提取字典中的特定参数,否则使用默认配置
params = task.get("params", {}) if isinstance(task, dict) else {}
saved_file = service.fetch_image(prompt, save_path, **params)
if saved_file:
results_log.append({"id": idx, "status": "success", "path": saved_file})
else:
results_log.append({"id": idx, "status": "failed", "prompt": prompt})
# 短暂休眠避免请求过载
time.sleep(0.5)
return results_log
# 使用示例
if __name__ == "__main__":
api_client = FluxImageService("http://your-server-ip:7860/api/generate")
my_prompts = [
"A futuristic laboratory with glowing blue potions, hyper-realistic, 8k",
{"text": "Cyberpunk cat sitting on a neon sign", "params": {"steps": 30, "guidance": 7.0}},
"Abstract oil painting of a stormy ocean at sunset"
]
run_batch_tasks(api_client, my_prompts, "batch_result_01")
容错与稳健性优化
在生产环境下,API 调用可能会因为显存溢出、网络抖动或后端服务重启而中断。引入重试机制和元数据保存是必要的工程实践。
1. 指数退避重试机制
通过装饰器或简单的循环逻辑,可以在请求失败时进行多次尝试,且尝试间隔逐渐增长,以应对临时性的服务不可用。
def robust_generate(service, prompt, path, retries=3):
for i in range(retries):
result = service.fetch_image(prompt, path)
if result:
return result
wait_time = (i + 1) * 5
print(f"任务失败,{wait_time}秒后进行第 {i+2} 次尝试...")
time.sleep(wait_time)
return None
2. 提示词与参数回溯
为了方便后续整理图像,建议在保存 PNG 文件的同时,将对应的 JSON 元数据一同保存,或者将参数写入图像的 Exif 信息中。以下是保存 JSON 元数据的简单实现:
import json
def save_with_meta(service, prompt, path, **params):
file_path = service.fetch_image(prompt, path, **params)
if file_path:
meta_data = {
"prompt": prompt,
"config": params,
"timestamp": time.time()
}
with open(path.replace(".png", ".json"), "w", encoding="utf-8") as f:
json.dump(meta_data, f, ensure_ascii=False, indent=4)
应用实例:游戏概念图矩阵生成
假设需要为游戏开发生成一系列不同环境下的角色草图,可以利用循环嵌套快速生成排列组合任务:
def generate_asset_matrix():
environments = ["Snowy Mountain", "Volcanic Cave", "Ancient Ruins"]
roles = ["Knight", "Mage", "Archer"]
client = FluxImageService()
for env in environments:
for role in roles:
prompt = f"Concept art of a {role} in a {env}, highly detailed, game asset style"
folder = f"assets/{env.replace(' ', '_')}"
os.makedirs(folder, exist_ok=True)
client.fetch_image(prompt, f"{folder}/{role}.png", steps=25)
# generate_asset_matrix()
通过上述 Python 脚本的封装与扩展,开发者可以将 FLUX.1-dev 从一个单纯的交互式绘图工具转变为可集成、可自动化的生产力引擎。这不仅适用于大规模素材生成,也为构建基于 AI 的下游应用提供了稳定的基础组件。