最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python調(diào)用Stable Diffusion API實現(xiàn)AI圖像生成的完整教程

 更新時間:2026年04月10日 08:56:46   作者:平安的平安  
本文介紹了從零開始學(xué)習(xí)使用Python調(diào)用Stable Diffusion API生成圖像的方法,包括本地部署、API調(diào)用、ControlNet、圖生圖等進(jìn)階技巧,還提供了高質(zhì)量Prompt模板、關(guān)鍵參數(shù)說明以及完整的使用流程,需要的朋友可以參考下

從零開始學(xué)習(xí)使用 Python 調(diào)用 Stable Diffusion API 生成圖像,涵蓋本地部署、API 調(diào)用、ControlNet、圖生圖等進(jìn)階技巧。

Python調(diào)用Stable Diffusion API實現(xiàn)AI圖像生成的完整教程

1. 技術(shù)架構(gòu)

1. 技術(shù)架構(gòu)

2. 圖像生成方式對比

2. 圖像生成方式對比

3. 環(huán)境準(zhǔn)備

3.1 本地部署 Stable Diffusion WebUI

# 克隆 Stable Diffusion WebUI
git 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. 核心代碼實現(xiàn)

4.1 SD API 客戶端封裝

# sd_client.py
import 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


@dataclass
class GenerationConfig:
    """圖像生成配置"""
    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 表示隨機(jī)
    batch_size: int = 1
    n_iter: int = 1  # 迭代次數(shù)
    model: Optional[str] = None


class StableDiffusionClient:
    """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

    # ---- 文生圖 ----
    def txt2img(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 in enumerate(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

    # ---- 圖生圖 ----
    def img2img(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()

        # 讀取初始圖片并轉(zhuǎn) base64
        with open(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 in enumerate(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

    # ---- 局部重繪 ----
    def inpaint(self, init_image_path: str, mask_image_path: str,
                prompt: str, denoising_strength: float = 0.85,
                output_dir: str = "./output") -> list[str]:
        """局部重繪:只修改 mask 區(qū)域"""
        with open(init_image_path, "rb") as f:
            init_images = [base64.b64encode(f.read()).decode()]
        with open(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 in enumerate(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

    # ---- 超分辨率 ----
    def upscale(self, image_path: str, scale: int = 2,
                output_dir: str = "./output") -> str:
        """使用 ESRGAN 進(jìn)行超分辨率放大"""
        with open(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)  # 等待模型加載

    def list_models(self) -> list[str]:
        """列出可用模型"""
        response = requests.get(f"{self.api_url}/sd-models")
        return [m["title"] for m in response.json()]

    def list_samplers(self) -> list[str]:
        """列出可用采樣器"""
        response = requests.get(f"{self.api_url}/samplers")
        return [s["name"] for s in response.json()]

4.2 批量生成示例

# batch_generate.py
from sd_client import StableDiffusionClient, GenerationConfig


def batch_generate_portraits():
    """批量生成人物肖像"""
    sd = StableDiffusionClient()

    # 查看可用模型和采樣器
    print("可用模型:", sd.list_models()[:5])
    print("可用采樣器:", sd.list_samplers())

    # 風(fēng)格列表
    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"風(fēng)格 [{style}] -> {paths}")


if __name__ == "__main__":
    batch_generate_portraits()

4.3 調(diào)用 Stability AI 云端 API

# stability_cloud.py
import requests
import base64
from pathlib import Path
from PIL import Image
from io import BytesIO


class StabilityAIClient:
    """Stability AI 官方云端 API"""

    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.stability.ai/v2beta"

    def generate(self, prompt: str, aspect_ratio: str = "1:1",
                 style: str = "photographic",
                 output_path: str = "output.png") -> str:
        """調(diào)用 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}")

        with open(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.py
from PIL import Image, ImageEnhance, ImageFilter
from pathlib import Path


class ImagePostProcessor:
    """圖像后處理:調(diào)整色彩、銳化、添加水印"""

    @staticmethod
    def enhance(image_path: str, brightness: float = 1.1,
                contrast: float = 1.15, sharpness: float = 1.3,
                output_path: str = None) -> str:
        """綜合增強(qiáng)"""
        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

    @staticmethod
    def add_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

    @staticmethod
    def create_grid(image_paths: list[str], cols: int = 3,
                    output_path: str = "grid.png") -> str:
        """將多張圖片拼成網(wǎng)格"""
        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 in enumerate(images):
            row, col = divmod(i, cols)
            grid.paste(img, (col * w, row * h))

        grid.save(output_path, quality=95)
        print(f"網(wǎng)格圖已保存: {output_path}")
        return output_path

5. Prompt 工程技巧

5. Prompt 工程技巧

高質(zhì)量 Prompt 模板

PROMPT_TEMPLATES = {
    "人物肖像": (
        "{subject}, {style}, detailed face, expressive eyes, "
        "dramatic lighting, masterpiece, best quality, ultra detailed"
    ),
    "風(fēng)景": (
        "{scene}, {mood}, volumetric lighting, god rays, "
        "landscape photography, 8k uhd, cinematic composition"
    ),
    "產(chǎn)品設(shè)計": (
        "{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. 關(guān)鍵參數(shù)影響

6. 關(guān)鍵參數(shù)影響

參數(shù)推薦值說明
steps25-35步數(shù)越多細(xì)節(jié)越好,但邊際遞減且更慢
cfg_scale7-12越高越遵循 prompt,過高會過飽和
samplerDPM++ 2M Karras兼顧速度與質(zhì)量
denoising_strength0.5-0.8圖生圖降噪強(qiáng)度,越高變化越大
seed-1隨機(jī)種子,固定可復(fù)現(xiàn)

7. 完整使用流程

# complete_demo.py
from sd_client import StableDiffusionClient, GenerationConfig
from stability_cloud import StabilityAIClient
from postprocess import ImagePostProcessor


def main():
    # ===== 方式一:本地 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. 總結(jié)

本文覆蓋了 Stable Diffusion 圖像生成的完整鏈路:

  1. 本地部署 SD WebUI 并開啟 API 模式
  2. 封裝 Python 客戶端 支持文生圖、圖生圖、局部重繪、超分辨率
  3. 云端 API 作為無 GPU 環(huán)境的替代方案
  4. Prompt 工程 模板化的提示詞編寫技巧
  5. 后處理管道 增強(qiáng)色彩、添加水印、拼圖網(wǎng)格

生成速度參考:RTX 4090 生成 512x512 約 3-5 秒,512x768 約 5-8 秒。云端 API 約 10-20 秒。

以上就是Python調(diào)用Stable Diffusion API實現(xiàn)AI圖像生成的完整教程的詳細(xì)內(nèi)容,更多關(guān)于Python調(diào)用Stable Diffusion API圖像生成的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python中atexit模塊的基本使用示例

    Python中atexit模塊的基本使用示例

    這篇文章主要介紹了Python中atexit模塊的基本使用示例,示例代碼基于Python2.x版本,注意其和Python3的兼容性,需要的朋友可以參考下
    2015-07-07
  • python編程控制Android手機(jī)操作技巧示例

    python編程控制Android手機(jī)操作技巧示例

    這篇文章主要為大家介紹了如何利用python編程來實現(xiàn)控制手機(jī)的操作技巧,文中含有各種操作的示例,有需要的朋友可以借鑒參考下
    2021-10-10
  • 詳解用Python練習(xí)畫個美隊盾牌

    詳解用Python練習(xí)畫個美隊盾牌

    這篇文章主要介紹了用Python練習(xí)畫個美隊盾牌,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • pyftplib中文亂碼問題解決方案

    pyftplib中文亂碼問題解決方案

    這篇文章主要介紹了pyftplib中文亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • python通過配置文件共享全局變量的實例

    python通過配置文件共享全局變量的實例

    今天小編就為大家分享一篇python通過配置文件共享全局變量的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python使用MYSQLDB實現(xiàn)從數(shù)據(jù)庫中導(dǎo)出XML文件的方法

    Python使用MYSQLDB實現(xiàn)從數(shù)據(jù)庫中導(dǎo)出XML文件的方法

    這篇文章主要介紹了Python使用MYSQLDB實現(xiàn)從數(shù)據(jù)庫中導(dǎo)出XML文件的方法,涉及Python使用MYSQLDB操作數(shù)據(jù)庫及XML文件的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • python中asyncore異步模塊的實現(xiàn)

    python中asyncore異步模塊的實現(xiàn)

    本文主要介紹了python中asyncore異步模塊的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Python高效實現(xiàn)HTML轉(zhuǎn)為Word和PDF

    Python高效實現(xiàn)HTML轉(zhuǎn)為Word和PDF

    在Python日常開發(fā)中,經(jīng)常會遇到將網(wǎng)頁中的 HTML 內(nèi)容保存為 Word 文檔,本文將借助第三方庫實現(xiàn)將HTML轉(zhuǎn)為Word和PDF,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-09-09
  • Python實現(xiàn)提取Excel嵌入圖片并重命名

    Python實現(xiàn)提取Excel嵌入圖片并重命名

    我們在日常辦公的時候經(jīng)常需要將Excel中嵌入單元的圖片進(jìn)行提取,并在提取的時候?qū)⑵渲械哪骋涣凶鳛樘崛〕鰣D片的命名,本文將使用Python實現(xiàn)這一功能,需要的可以了解下
    2025-04-04
  • Python中用xlwt制作表格實例講解

    Python中用xlwt制作表格實例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于Python中用xlwt制作表格實例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2020-11-11

最新評論

博爱县| 任丘市| 上犹县| 周口市| 鄂伦春自治旗| 定边县| 吴桥县| 河西区| 醴陵市| 石首市| 巍山| 耒阳市| 达尔| 进贤县| 陈巴尔虎旗| 巴彦淖尔市| 铁岭县| 綦江县| 高邑县| 邯郸市| 樟树市| 汾西县| 怀远县| 凭祥市| 阿坝| 孙吴县| 平顶山市| 西藏| 望江县| 太康县| 东源县| 沙田区| 曲沃县| 逊克县| 通河县| 广饶县| 荣昌县| 永福县| 舞阳县| 长垣县| 莱阳市|