176 lines
5.9 KiB
Python
176 lines
5.9 KiB
Python
|
import json
|
|||
|
import logging
|
|||
|
import os
|
|||
|
from typing import Optional, List
|
|||
|
|
|||
|
from fastapi import APIRouter, HTTPException
|
|||
|
from pydantic import BaseModel
|
|||
|
|
|||
|
from Liblib.Kit.PuLIDGenerator import PuLIDGenerator
|
|||
|
|
|||
|
# 创建路由路由器
|
|||
|
router = APIRouter(prefix="/api/copyface", tags=["人像换脸"])
|
|||
|
|
|||
|
# 配置日志
|
|||
|
logger = logging.getLogger(__name__)
|
|||
|
|
|||
|
# JSON配置文件路径
|
|||
|
COPY_FACE_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "..", "Liblib", "Data", "copy_face_image_data.json")
|
|||
|
|
|||
|
class CopyFaceRequest(BaseModel):
|
|||
|
image_url: str
|
|||
|
|
|||
|
class ModelSample(BaseModel):
|
|||
|
name: str
|
|||
|
template_uuid: str
|
|||
|
steps: int
|
|||
|
width: int
|
|||
|
height: int
|
|||
|
cfgScale: float
|
|||
|
sampler: str
|
|||
|
seed: int
|
|||
|
prompt: str
|
|||
|
negative_prompt: Optional[str] = None
|
|||
|
reference_image_url: str
|
|||
|
control_weight: float
|
|||
|
|
|||
|
@router.get("/samples", response_model=List[ModelSample])
|
|||
|
async def get_available_samples():
|
|||
|
"""
|
|||
|
获取所有可用的生成样例配置
|
|||
|
|
|||
|
Returns:
|
|||
|
包含所有可用模型样例的列表
|
|||
|
"""
|
|||
|
try:
|
|||
|
# 读取配置文件
|
|||
|
with open(COPY_FACE_CONFIG_PATH, 'r', encoding='utf-8') as f:
|
|||
|
config_data = json.load(f)
|
|||
|
|
|||
|
# 返回所有模型配置
|
|||
|
return config_data["models"]
|
|||
|
|
|||
|
except FileNotFoundError:
|
|||
|
logger.error(f"配置文件未找到: {COPY_FACE_CONFIG_PATH}")
|
|||
|
raise HTTPException(status_code=404, detail="配置文件未找到")
|
|||
|
except json.JSONDecodeError:
|
|||
|
logger.error(f"配置文件格式错误: {COPY_FACE_CONFIG_PATH}")
|
|||
|
raise HTTPException(status_code=500, detail="配置文件格式错误")
|
|||
|
except Exception as e:
|
|||
|
logger.error(f"获取样例配置失败: {str(e)}")
|
|||
|
raise HTTPException(status_code=500, detail=f"获取样例配置失败: {str(e)}")
|
|||
|
|
|||
|
@router.post("/generate", response_model=dict)
|
|||
|
async def generate_copy_face(request: CopyFaceRequest):
|
|||
|
"""
|
|||
|
根据提供的图片URL生成模拟人脸图片(使用默认配置)
|
|||
|
|
|||
|
Args:
|
|||
|
request: 包含图片URL的请求体
|
|||
|
|
|||
|
Returns:
|
|||
|
包含生成图片OBS地址的字典
|
|||
|
"""
|
|||
|
try:
|
|||
|
# 读取默认配置(第一个模型)
|
|||
|
with open(COPY_FACE_CONFIG_PATH, 'r', encoding='utf-8') as f:
|
|||
|
config_data = json.load(f)
|
|||
|
|
|||
|
default_config = config_data["models"][0]
|
|||
|
|
|||
|
# 使用默认配置
|
|||
|
generator = PuLIDGenerator()
|
|||
|
|
|||
|
# 设置默认参数
|
|||
|
generator.set_default_params(
|
|||
|
template_uuid=default_config["template_uuid"],
|
|||
|
steps=default_config["steps"],
|
|||
|
width=default_config["width"],
|
|||
|
height=default_config["height"]
|
|||
|
)
|
|||
|
|
|||
|
# 生成图像
|
|||
|
obs_url = generator.generate_image(
|
|||
|
prompt=default_config["prompt"],
|
|||
|
reference_image_url=request.image_url,
|
|||
|
control_weight=default_config["control_weight"]
|
|||
|
)
|
|||
|
|
|||
|
if obs_url:
|
|||
|
logger.info(f"人像换脸生成成功,OBS地址: {obs_url}")
|
|||
|
return {
|
|||
|
"status": "success",
|
|||
|
"obs_url": obs_url,
|
|||
|
"message": "人像换脸生成成功",
|
|||
|
"model_used": default_config["name"]
|
|||
|
}
|
|||
|
else:
|
|||
|
logger.error("人像换脸生成失败")
|
|||
|
raise HTTPException(status_code=500, detail="人像换脸生成失败")
|
|||
|
|
|||
|
except Exception as e:
|
|||
|
logger.error(f"人像换脸请求处理失败: {str(e)}")
|
|||
|
raise HTTPException(status_code=500, detail=f"人像换脸请求处理失败: {str(e)}")
|
|||
|
|
|||
|
@router.post("/generate/{model_name}", response_model=dict)
|
|||
|
async def generate_copy_face_with_model(model_name: str, request: CopyFaceRequest):
|
|||
|
"""
|
|||
|
根据指定的模型名称和图片URL生成模拟人脸图片
|
|||
|
|
|||
|
Args:
|
|||
|
model_name: 模型名称(如:炫酷机甲美女_majicflus)
|
|||
|
request: 包含图片URL的请求体
|
|||
|
|
|||
|
Returns:
|
|||
|
包含生成图片OBS地址的字典
|
|||
|
"""
|
|||
|
try:
|
|||
|
# 读取配置文件
|
|||
|
with open(COPY_FACE_CONFIG_PATH, 'r', encoding='utf-8') as f:
|
|||
|
config_data = json.load(f)
|
|||
|
|
|||
|
# 查找指定的模型配置
|
|||
|
model_config = None
|
|||
|
for model in config_data["models"]:
|
|||
|
if model["name"] == model_name:
|
|||
|
model_config = model
|
|||
|
break
|
|||
|
|
|||
|
if not model_config:
|
|||
|
raise HTTPException(status_code=404, detail=f"未找到模型: {model_name}")
|
|||
|
|
|||
|
# 使用指定配置
|
|||
|
generator = PuLIDGenerator()
|
|||
|
|
|||
|
# 设置参数
|
|||
|
generator.set_default_params(
|
|||
|
template_uuid=model_config["template_uuid"],
|
|||
|
steps=model_config["steps"],
|
|||
|
width=model_config["width"],
|
|||
|
height=model_config["height"]
|
|||
|
)
|
|||
|
|
|||
|
# 生成图像
|
|||
|
obs_url = generator.generate_image(
|
|||
|
prompt=model_config["prompt"],
|
|||
|
reference_image_url=request.image_url,
|
|||
|
control_weight=model_config["control_weight"]
|
|||
|
)
|
|||
|
|
|||
|
if obs_url:
|
|||
|
logger.info(f"人像换脸生成成功,模型: {model_name}, OBS地址: {obs_url}")
|
|||
|
return {
|
|||
|
"status": "success",
|
|||
|
"obs_url": obs_url,
|
|||
|
"message": "人像换脸生成成功",
|
|||
|
"model_used": model_name
|
|||
|
}
|
|||
|
else:
|
|||
|
logger.error(f"人像换脸生成失败,模型: {model_name}")
|
|||
|
raise HTTPException(status_code=500, detail="人像换脸生成失败")
|
|||
|
|
|||
|
except HTTPException:
|
|||
|
raise
|
|||
|
except Exception as e:
|
|||
|
logger.error(f"人像换脸请求处理失败: {str(e)}")
|
|||
|
raise HTTPException(status_code=500, detail=f"人像换脸请求处理失败: {str(e)}")
|