Python AI 绘画

Calling image APIs, running local diffusion models, and handling the async/polling pattern.

Intermediate
Key PointsImage APIs are slow (5-30s) — treat them as async jobs with polling, not as a synchronous request in your web handler.

Call an Image API

APIs return either a URL or base64. Base64 can be written straight to disk; URLs expire and may be hotlink-protected.

Python
import base64
from pathlib import Path
from openai import OpenAI

client = OpenAI(timeout=120)

resp = client.images.generate(
    model="gpt-image-1",
    prompt="a minimal isometric illustration of a database server, flat colors",
    size="1024x1024",
    n=1,
)
b64 = resp.data[0].b64_json
Path("out.png").write_bytes(base64.b64decode(b64))
print("saved", Path("out.png").stat().st_size, "bytes")
Output
saved 1048576 bytes

Post-processing with Pillow

Common post-processing — resize, crop, watermark, convert to WebP — is one Pillow chain; OpenCV is overkill.

Python
from PIL import Image

img = Image.open("out.png").convert("RGB")
img.thumbnail((512, 512))                 # 等比缩放,不放大
img.save("out.webp", "WEBP", quality=82)

print(img.size)
Output
(512, 512)

Local Diffusion

Running Stable Diffusion locally needs GPU VRAM (6GB+). diffusers is the usual wrapper; first run downloads gigabytes of weights.

Python
from diffusers import StableDiffusionPipeline
import torch

pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
).to("cuda")

image = pipe("a cat sitting on a server rack, studio light", num_inference_steps=25).images[0]
image.save("cat.png")
Never generate images synchronously inside a web request — 10-30s per call saturates workers. Queue it, return a job id, poll or callback.

Friends & Partners