Python 实现 AI 图像生成:调用 Stable Diffusion API 完整教程

Python 实现 AI 图像生成:调用 Stable Diffusion API 完整教程

从零开始学习使用 Python 调用 Stable Diffusion API 生成图像,涵盖本地部署、API 调用、ControlNet、图生图等进阶技巧。

1. 技术架构

Python 客户端

Stable Diffusion API

本地部署
SD WebUI / ComfyUI

云端 API
Replicate / Stability AI

Stable Diffusion 模型

文生图
txt2img

图生图
img2img

局部重绘
inpainting

超分辨率
upscale

输出图像

后处理管道

存储
本地/OSS

2. 图像生成方式对比

50%25%15%10%各生成方式使用占比统计文生图 (txt2img)图生图 (img2img)局部重绘 (inpainting)超分辨率 (upscale)

3. 环境准备

3.1 本地部署 Stable Diffusion WebUI

# 克隆 Stable Diffusion WebUIgit clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git cd stable-diffusion-webui # 启动(开启 API 模式) ./webui.sh --api--listen# Windows 用户 webui.bat --api--listen

3.2 安装依赖

pip install requests Pillow io base64 

4. 核心代码实现

4.1 SD API 客户端封装

# sd_client.pyimport requests import base64 import io import json import time from pathlib import Path from PIL import Image from dataclasses import dataclass, field from typing import Optional @dataclassclassGenerationConfig:"""图像生成配置""" prompt:str="" negative_prompt:str="low quality, blurry, deformed" width:int=512 height:int=512 steps:int=30 cfg_scale:float=7.0 sampler_name:str="DPM++ 2M Karras" seed:int=-1# -1 表示随机 batch_size:int=1 n_iter:int=1# 迭代次数 model: Optional[str]=NoneclassStableDiffusionClient:"""Stable Diffusion API 客户端"""def__init__(self, base_url:str="http://127.0.0.1:7860"): self.base_url = base_url self.api_url =f"{base_url}/sdapi/v1"def_save_base64_image(self, b64_str:str, output_path:str)->str:"""将 base64 图片保存到文件""" img_data = base64.b64decode(b64_str) img = Image.open(io.BytesIO(img_data)) img.save(output_path)return output_path # ---- 文生图 ----deftxt2img(self, config: GenerationConfig, output_dir:str="./output")->list[str]:"""文生图:从文本描述生成图像""" payload ={"prompt": config.prompt,"negative_prompt": config.negative_prompt,"width": config.width,"height": config.height,"steps": config.steps,"cfg_scale": config.cfg_scale,"sampler_name": config.sampler_name,"seed": config.seed,"batch_size": config.batch_size,"n_iter": config.n_iter,}if config.model: self._switch_model(config.model) response = requests.post(f"{self.api_url}/txt2img", json=payload) response.raise_for_status() data = response.json() Path(output_dir).mkdir(exist_ok=True) saved_paths =[]for i, img_b64 inenumerate(data["images"]): path =f"{output_dir}/txt2img_{int(time.time())}_{i}.png" self._save_base64_image(img_b64, path) saved_paths.append(path)print(f"已保存: {path}")return saved_paths # ---- 图生图 ----defimg2img(self, init_image_path:str, prompt:str, denoising_strength:float=0.75, config: GenerationConfig =None, output_dir:str="./output")->list[str]:"""图生图:基于参考图 + 提示词生成新图""" config = config or GenerationConfig()# 读取初始图片并转 base64withopen(init_image_path,"rb")as f: init_images =[base64.b64encode(f.read()).decode()] payload ={"init_images": init_images,"prompt": prompt,"negative_prompt": config.negative_prompt,"width": config.width,"height": config.height,"steps": config.steps,"cfg_scale": config.cfg_scale,"sampler_name": config.sampler_name,"denoising_strength": denoising_strength,"seed": config.seed,} response = requests.post(f"{self.api_url}/img2img", json=payload) response.raise_for_status() data = response.json() Path(output_dir).mkdir(exist_ok=True) saved_paths =[]for i, img_b64 inenumerate(data["images"]): path =f"{output_dir}/img2img_{int(time.time())}_{i}.png" self._save_base64_image(img_b64, path) saved_paths.append(path)print(f"已保存: {path}")return saved_paths # ---- 局部重绘 ----definpaint(self, init_image_path:str, mask_image_path:str, prompt:str, denoising_strength:float=0.85, output_dir:str="./output")->list[str]:"""局部重绘:只修改 mask 区域"""withopen(init_image_path,"rb")as f: init_images =[base64.b64encode(f.read()).decode()]withopen(mask_image_path,"rb")as f: mask = base64.b64encode(f.read()).decode() payload ={"init_images": init_images,"mask": mask,"prompt": prompt,"negative_prompt":"low quality, blurry","denoising_strength": denoising_strength,"inpainting_fill":1,# 0=fill, 1=original, 2=latent noise"inpaint_full_res":True,"steps":30,"cfg_scale":7.0,"sampler_name":"DPM++ 2M Karras","width":512,"height":512,} response = requests.post(f"{self.api_url}/img2img", json=payload) response.raise_for_status() data = response.json() Path(output_dir).mkdir(exist_ok=True) saved_paths =[]for i, img_b64 inenumerate(data["images"]): path =f"{output_dir}/inpaint_{int(time.time())}_{i}.png" self._save_base64_image(img_b64, path) saved_paths.append(path)return saved_paths # ---- 超分辨率 ----defupscale(self, image_path:str, scale:int=2, output_dir:str="./output")->str:"""使用 ESRGAN 进行超分辨率放大"""withopen(image_path,"rb")as f: img_b64 = base64.b64encode(f.read()).decode() payload ={"image": img_b64,"upscaler_1":"R-ESRGAN 4x+","upscaling_resize": scale,} response = requests.post(f"{self.api_url}/extra-single-image", json=payload) response.raise_for_status() data = response.json() Path(output_dir).mkdir(exist_ok=True) path =f"{output_dir}/upscaled_{int(time.time())}.png" self._save_base64_image(data["image"], path)print(f"超分辨率完成: {path}")return path # ---- 模型管理 ----def_switch_model(self, model_name:str):"""切换模型""" response = requests.post(f"{self.api_url}/options", json={"sd_model_checkpoint": model_name},) response.raise_for_status() time.sleep(3)# 等待模型加载deflist_models(self)->list[str]:"""列出可用模型""" response = requests.get(f"{self.api_url}/sd-models")return[m["title"]for m in response.json()]deflist_samplers(self)->list[str]:"""列出可用采样器""" response = requests.get(f"{self.api_url}/samplers")return[s["name"]for s in response.json()]

4.2 批量生成示例

# batch_generate.pyfrom sd_client import StableDiffusionClient, GenerationConfig defbatch_generate_portraits():"""批量生成人物肖像""" sd = StableDiffusionClient()# 查看可用模型和采样器print("可用模型:", sd.list_models()[:5])print("可用采样器:", sd.list_samplers())# 风格列表 styles =["cyberpunk neon city","watercolor painting","oil painting renaissance","anime style","photorealistic 8k",] base_prompt =("portrait of a young woman, detailed face, beautiful eyes, ""dramatic lighting, masterpiece, best quality")for style in styles: config = GenerationConfig( prompt=f"{base_prompt}, {style}", negative_prompt="lowres, bad anatomy, bad hands, text, error", width=512, height=768, steps=30, cfg_scale=7.5,) paths = sd.txt2img(config, output_dir=f"./output/{style.replace(' ','_')}")print(f"风格 [{style}] -> {paths}")if __name__ =="__main__": batch_generate_portraits()

4.3 调用 Stability AI 云端 API

# stability_cloud.pyimport requests import base64 from pathlib import Path from PIL import Image from io import BytesIO classStabilityAIClient:"""Stability AI 官方云端 API"""def__init__(self, api_key:str): self.api_key = api_key self.base_url ="https://api.stability.ai/v2beta"defgenerate(self, prompt:str, aspect_ratio:str="1:1", style:str="photographic", output_path:str="output.png")->str:"""调用 Stable Diffusion 3 生成图像""" response = requests.post(f"{self.base_url}/stable-image/generate/sd3", headers={"Authorization":f"Bearer {self.api_key}","Accept":"image/*",}, files={"none":""}, data={"prompt": prompt,"aspect_ratio": aspect_ratio,"style_preset": style,"output_format":"png",},)if response.status_code !=200:raise Exception(f"API 错误: {response.status_code} - {response.text}")withopen(output_path,"wb")as f: f.write(response.content)print(f"已生成: {output_path}")return output_path # 使用示例if __name__ =="__main__": client = StabilityAIClient(api_key="sk-your-api-key") client.generate( prompt="A majestic dragon flying over a neon-lit cyberpunk city at night, ""highly detailed, cinematic lighting, 8k", aspect_ratio="16:9", style="cinematic", output_path="dragon_city.png",)

4.4 图像后处理管道

# postprocess.pyfrom PIL import Image, ImageEnhance, ImageFilter from pathlib import Path classImagePostProcessor:"""图像后处理:调整色彩、锐化、添加水印"""@staticmethoddefenhance(image_path:str, brightness:float=1.1, contrast:float=1.15, sharpness:float=1.3, output_path:str=None)->str:"""综合增强""" img = Image.open(image_path) img = ImageEnhance.Brightness(img).enhance(brightness) img = ImageEnhance.Contrast(img).enhance(contrast) img = ImageEnhance.Sharpness(img).enhance(sharpness) output_path = output_path or image_path.replace(".","_enhanced.") img.save(output_path, quality=95)return output_path @staticmethoddefadd_watermark(image_path:str, text:str="AI Generated", output_path:str=None)->str:"""添加水印"""from PIL import ImageDraw, ImageFont img = Image.open(image_path).convert("RGBA") overlay = Image.new("RGBA", img.size,(0,0,0,0)) draw = ImageDraw.Draw(overlay)# 半透明白色文字 draw.text((img.width -200, img.height -40), text, fill=(255,255,255,128),) img = Image.alpha_composite(img, overlay).convert("RGB") output_path = output_path or image_path.replace(".","_wm.") img.save(output_path, quality=95)return output_path @staticmethoddefcreate_grid(image_paths:list[str], cols:int=3, output_path:str="grid.png")->str:"""将多张图片拼成网格""" images =[Image.open(p)for p in image_paths] w, h = images[0].size rows =(len(images)+ cols -1)// cols grid = Image.new("RGB",(w * cols, h * rows),"white")for i, img inenumerate(images): row, col =divmod(i, cols) grid.paste(img,(col * w, row * h)) grid.save(output_path, quality=95)print(f"网格图已保存: {output_path}")return output_path 

5. Prompt 工程技巧

Prompt 结构

主体描述

风格关键词

质量修饰词

负面提示词

高质量 Prompt 模板

PROMPT_TEMPLATES ={"人物肖像":("{subject}, {style}, detailed face, expressive eyes, ""dramatic lighting, masterpiece, best quality, ultra detailed"),"风景":("{scene}, {mood}, volumetric lighting, god rays, ""landscape photography, 8k uhd, cinematic composition"),"产品设计":("{product}, minimalist design, studio lighting, ""white background, product photography, professional, 4k"),"动漫":("{character}, anime style, vibrant colors, ""detailed illustration, cel shading, masterpiece"),} NEGATIVE_PROMPTS ={"通用":"lowres, bad anatomy, bad hands, text, error, missing fingers, ""extra digit, cropped, worst quality, low quality, blurry","写实":"illustration, painting, drawing, art, sketch, anime, cartoon, ""CG, render, 3D, watermark, text, font, signature","动漫":"photo, realistic, 3d, western, ugly, duplicate, morbid, ""deformed, bad anatomy, blurry",}

6. 关键参数影响

35%20%15%15%10%5%不同参数对生成质量的影响权重Prompt 质量采样步数 (steps)CFG Scale采样器选择模型选择分辨率

参数推荐值说明
steps25-35步数越多细节越好,但边际递减且更慢
cfg_scale7-12越高越遵循 prompt,过高会过饱和
samplerDPM++ 2M Karras兼顾速度与质量
denoising_strength0.5-0.8图生图降噪强度,越高变化越大
seed-1随机种子,固定可复现

7. 完整使用流程

# complete_demo.pyfrom sd_client import StableDiffusionClient, GenerationConfig from stability_cloud import StabilityAIClient from postprocess import ImagePostProcessor defmain():# ===== 方式一:本地 SD WebUI ===== sd = StableDiffusionClient("http://127.0.0.1:7860")# 文生图 config = GenerationConfig( prompt="A serene Japanese garden with cherry blossoms, ""koi pond, stone bridge, golden hour, cinematic, 8k", negative_prompt="lowres, blurry, text, watermark", width=768, height=512, steps=30, cfg_scale=7.5,) paths = sd.txt2img(config)print(f"生成完成: {paths}")# 图生图if paths: new_paths = sd.img2img( init_image_path=paths[0], prompt="same scene but in autumn, orange and red leaves, snow", denoising_strength=0.6,)print(f"图生图完成: {new_paths}")# 超分辨率if paths: upscaled = sd.upscale(paths[0], scale=2)print(f"超分辨率完成: {upscaled}")# 后处理 pp = ImagePostProcessor()if paths: enhanced = pp.enhance(paths[0]) watermarked = pp.add_watermark(enhanced, text="AI Art")print(f"后处理完成: {watermarked}")# ===== 方式二:云端 API =====# cloud = StabilityAIClient("sk-xxx")# cloud.generate("A futuristic cityscape at sunset", "16:9", "cinematic")if __name__ =="__main__": main()

8. 总结

本文覆盖了 Stable Diffusion 图像生成的完整链路:

  1. 本地部署 SD WebUI 并开启 API 模式
  2. 封装 Python 客户端 支持文生图、图生图、局部重绘、超分辨率
  3. 云端 API 作为无 GPU 环境的替代方案
  4. Prompt 工程 模板化的提示词编写技巧
  5. 后处理管道 增强色彩、添加水印、拼图网格
生成速度参考:RTX 4090 生成 512x512 约 3-5 秒,512x768 约 5-8 秒。云端 API 约 10-20 秒。

Read more

faster-whisper极速安装指南:3分钟搞定AI语音转文字

还在为语音转文字的慢速度而烦恼吗?faster-whisper来拯救你!这款基于OpenAI Whisper模型的优化版本,通过CTranslate2推理引擎实现了4倍速的语音识别,同时保持相同的准确率。无论你是开发者还是技术爱好者,这篇指南将带你轻松上手这个强大的AI语音识别工具。 【免费下载链接】faster-whisper 项目地址: https://gitcode.com/gh_mirrors/fas/faster-whisper 🚀 一分钟快速安装 安装faster-whisper就像呼吸一样简单!只需要一个命令: pip install faster-whisper 是的,就这么简单!Python包管理器会自动处理所有依赖关系,让你在几秒钟内就能开始使用这个强大的语音转文字工具。 VAD语音活动检测模块 - 智能过滤静音片段 🛠️ 硬件环境准备 基础要求 * Python 3.8或更高版本 * 支持CUDA的NVIDIA GPU(推荐)或普通CPU GPU用户专属配置 如果你拥有NVIDIA显卡,为了获得最佳性能,需要安装以下组件:

2026-01-14 学习记录--LLM-申请Hugging Face 访问令牌(以Meta-Llama-3.1-8B-Instruct为例)

2026-01-14 学习记录--LLM-申请Hugging Face 访问令牌(以Meta-Llama-3.1-8B-Instruct为例)

LLM-申请 Hugging Face 访问令牌(以Meta-Llama-3.1-8B-Instruct为例) 一、请求访问Llama模型 ⭐️ 随便进入想要访问的Llama模型,这里展示的是Meta-Llama-3-8B-Instruct。 1、 点击链接,申请访问Llama模型 2、 填写相关申请信息,注意如下:👇🏻(1)、国家最好选「美国」,然后填 「美国的大学」;(2)、操作这一步时,节点需要是对应国家的节点(若是美国,那么节点也要是美国)。 3、 提交成功后,就可开始申请Llama模型的Hugging Face 访问令牌啦~ 二、申请Llama模型的Hugging Face 访问令牌(以Meta-Llama-3.1-8B-Instruct为例)⭐️ 1、判断是否需要申请 访问Meta-Llama-3.1-8B-Instruct模型在Hugging Face上的官方仓库。 假若你看见“You need to agree to share your

Ollama 底层的 llama.cpp 和 GGUF

GGUF = 大模型权重的「通用压缩格式」(类似视频的 MP4,适配所有播放器) llama.cpp = 跑 GGUF 格式模型的「轻量级推理引擎」(类似视频播放器,能在低配电脑上流畅播 MP4) 两者配合:GGUF 让模型体积变小、适配性强,llama.cpp 让模型能在 CPU / 低配 GPU 上快速跑 这也是 Ollama 能做到 “一键本地运行” 的底层原因 GGUF 详解:大模型的 “通用压缩包” 核心定义 GGUF(Generic GGML Format)是 GGML 格式的升级版,是专门为大模型权重设计的二进制存储格式 核心目标是「通用、高效、压缩」 GGML 是什么?

开源浪潮下的中国力量:文心一言大模型本地部署与应用全攻略

开源浪潮下的中国力量:文心一言大模型本地部署与应用全攻略

文章目录 * 一、前言 * 1.1 模型开源意义与背景 * 1.2 文心一言大模型简介 * 1.3 测评目标与思路 * 二、文心一言大模型 * 2.1 文心一言开源概况 * 2.2 文心一言大模型技术综述 * 三、文心一言大模型深度解析 * 3.1 开源策略与生态影响 * 3.1.1 开源时间与版本介绍 * 3.2 模型特性与优势 * 四、部署实战:从 GitCode下载ERNIE-4.5-0.3B 模型到本地可交互服务 * 4.1 环境准备与部署方式 * 4.2 下载与安装步骤 * 4.3 调用示例与接口说明 * 编写部署测试脚本 * 五、