This commit is contained in:
2026-04-12 01:02:14 +08:00
parent 509487f155
commit 9b053e302b
14085 changed files with 2680009 additions and 12 deletions

View File

@@ -0,0 +1,76 @@
"""Replicate 图像生成服务封装。"""
import uuid
from pathlib import Path
import httpx
import replicate
GENERATED_DIR = Path(__file__).parent.parent.parent / "generated"
async def _download_image(url: str) -> str:
"""下载远程图片到本地 generated/ 目录,返回本地 URL 路径。"""
filename = f"{uuid.uuid4().hex}.png"
filepath = GENERATED_DIR / filename
async with httpx.AsyncClient() as client:
resp = await client.get(url, follow_redirects=True)
resp.raise_for_status()
filepath.write_bytes(resp.content)
return f"/generated/{filename}"
async def generate_images(
prompt: str,
num_images: int = 1,
ref_image_url: str | None = None,
) -> list[str]:
"""
调用 Replicate 生成图片。
返回本地可访问的图片 URL 列表。
"""
local_urls = []
for _ in range(num_images):
try:
if ref_image_url and ref_image_url.startswith("/"):
# 本地路径转为 file URI 不适用于 Replicate
# 需要用户上传的图先通过后端 URL 访问
# MVP 阶段:参考图作为 prompt 的文字补充,不直接传给模型
# 仅使用 flux-schnell 文生图
output = await replicate.async_run(
"black-forest-labs/flux-schnell",
input={
"prompt": prompt,
"num_outputs": 1,
"aspect_ratio": "1:1",
"output_format": "png",
},
)
else:
output = await replicate.async_run(
"black-forest-labs/flux-schnell",
input={
"prompt": prompt,
"num_outputs": 1,
"aspect_ratio": "1:1",
"output_format": "png",
},
)
# output 是 FileOutput 列表或单个 URL
if isinstance(output, list):
for item in output:
url = str(item)
local_url = await _download_image(url)
local_urls.append(local_url)
else:
url = str(output)
local_url = await _download_image(url)
local_urls.append(local_url)
except Exception as e:
local_urls.append(f"[生成失败: {e}]")
return local_urls