182 lines
5.1 KiB
Python
182 lines
5.1 KiB
Python
"""图片生成 API 路由"""
|
||
|
||
from typing import Optional
|
||
|
||
from fastapi import APIRouter, HTTPException, status
|
||
from pydantic import BaseModel, Field
|
||
|
||
from app.services.image_generator import (
|
||
IMAGE_STYLES,
|
||
LAYOUT_OPTIONS,
|
||
ImageGenerator,
|
||
ImageGenerationError,
|
||
PLATFORM_IMAGE_SPECS,
|
||
)
|
||
|
||
router = APIRouter(prefix="/image", tags=["图片生成"])
|
||
|
||
|
||
class GenerateCoverRequest(BaseModel):
|
||
"""生成封面图请求"""
|
||
title: str = Field(..., description="文章标题")
|
||
platform: str = Field(..., description="目标平台")
|
||
image_type: str = Field(default="cover", description="图片类型: cover/inline")
|
||
style: str = Field(default="modern", description="风格选项")
|
||
layout: str = Field(default="centered", description="排版选项")
|
||
custom_prompt: Optional[str] = Field(default=None, description="自定义提示词")
|
||
|
||
|
||
class ImageResultResponse(BaseModel):
|
||
"""图片生成结果响应"""
|
||
url: str
|
||
width: int
|
||
height: int
|
||
prompt: str
|
||
platform: str
|
||
task_id: str
|
||
|
||
|
||
class ImageSpecsResponse(BaseModel):
|
||
"""平台图片规格响应"""
|
||
platform: str
|
||
specs: dict
|
||
|
||
|
||
class StyleOption(BaseModel):
|
||
"""风格选项"""
|
||
value: str
|
||
name: str
|
||
|
||
|
||
class LayoutOption(BaseModel):
|
||
"""排版选项"""
|
||
value: str
|
||
name: str
|
||
|
||
|
||
class ImageConfigResponse(BaseModel):
|
||
"""图片生成配置响应"""
|
||
platforms: list[str]
|
||
styles: list[StyleOption]
|
||
layouts: list[LayoutOption]
|
||
|
||
|
||
@router.post("/generate-cover", response_model=ImageResultResponse)
|
||
async def generate_cover(request: GenerateCoverRequest):
|
||
"""生成封面图
|
||
|
||
基于阿里云百炼(万相-文生图V1)生成封面图,自动适配目标平台的尺寸规格。
|
||
|
||
Args:
|
||
request: 生成请求参数
|
||
|
||
Returns:
|
||
ImageResultResponse: 包含图片URL和元数据
|
||
|
||
Raises:
|
||
HTTPException: 当平台不支持或API调用失败时
|
||
"""
|
||
# 验证平台是否支持
|
||
supported_platforms = ImageGenerator.get_supported_platforms()
|
||
if request.platform not in supported_platforms:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail=f"不支持的平台: {request.platform},支持的平台: {', '.join(supported_platforms)}",
|
||
)
|
||
|
||
# 验证风格选项
|
||
if request.style not in IMAGE_STYLES:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail=f"不支持的风格: {request.style},支持的风格: {', '.join(IMAGE_STYLES.keys())}",
|
||
)
|
||
|
||
# 验证排版选项
|
||
if request.layout not in LAYOUT_OPTIONS:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail=f"不支持的排版: {request.layout},支持的排版: {', '.join(LAYOUT_OPTIONS.keys())}",
|
||
)
|
||
|
||
# 验证图片类型
|
||
if request.image_type not in ("cover", "inline"):
|
||
raise HTTPException(
|
||
status_code=status.HTTP_400_BAD_REQUEST,
|
||
detail="图片类型只支持: cover, inline",
|
||
)
|
||
|
||
generator = ImageGenerator()
|
||
|
||
try:
|
||
result = await generator.generate_cover(
|
||
title=request.title,
|
||
platform=request.platform,
|
||
image_type=request.image_type,
|
||
style=request.style,
|
||
layout=request.layout,
|
||
custom_prompt=request.custom_prompt,
|
||
)
|
||
|
||
return ImageResultResponse(
|
||
url=result.url,
|
||
width=result.width,
|
||
height=result.height,
|
||
prompt=result.prompt,
|
||
platform=result.platform,
|
||
task_id=result.task_id,
|
||
)
|
||
|
||
except ImageGenerationError as e:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||
detail=f"图片生成失败: {str(e)}",
|
||
)
|
||
|
||
|
||
@router.get("/platforms", response_model=list[str])
|
||
async def get_supported_platforms():
|
||
"""获取支持的平台列表"""
|
||
return ImageGenerator.get_supported_platforms()
|
||
|
||
|
||
@router.get("/platforms/{platform}/specs", response_model=ImageSpecsResponse)
|
||
async def get_platform_specs(platform: str):
|
||
"""获取指定平台的图片规格
|
||
|
||
Args:
|
||
platform: 平台标识
|
||
|
||
Returns:
|
||
ImageSpecsResponse: 平台图片规格
|
||
|
||
Raises:
|
||
HTTPException: 当平台不支持时
|
||
"""
|
||
specs = ImageGenerator.get_platform_specs(platform)
|
||
if specs is None:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
detail=f"不支持的平台: {platform}",
|
||
)
|
||
|
||
return ImageSpecsResponse(platform=platform, specs=specs)
|
||
|
||
|
||
@router.get("/config", response_model=ImageConfigResponse)
|
||
async def get_image_config():
|
||
"""获取图片生成配置(风格、排版选项等)"""
|
||
styles = [
|
||
StyleOption(value=key, name=value["name"])
|
||
for key, value in IMAGE_STYLES.items()
|
||
]
|
||
|
||
layouts = [
|
||
LayoutOption(value=key, name=value["name"])
|
||
for key, value in LAYOUT_OPTIONS.items()
|
||
]
|
||
|
||
return ImageConfigResponse(
|
||
platforms=ImageGenerator.get_supported_platforms(),
|
||
styles=styles,
|
||
layouts=layouts,
|
||
) |