TravelContentCreator/poster/poster_generator.py

121 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
海报生成器模块
"""
import os
import logging
import random
from typing import List, Dict, Any, Optional, Union, Tuple
from pathlib import Path
from PIL import Image
from core.config import ConfigManager, PosterConfig
from utils.file_io import OutputManager
from .templates.base_template import BaseTemplate
from .templates.vibrant_template import VibrantTemplate
from .templates.business_template import BusinessTemplate
from .templates.collage_template import CollageTemplate
from .utils import ImageProcessor
logger = logging.getLogger(__name__)
class PosterGenerator:
"""
海报生成器
负责根据文本内容和配置生成海报图像
"""
def __init__(self, config_manager: ConfigManager, output_manager: OutputManager):
"""
初始化海报生成器
Args:
config_manager: 配置管理器
output_manager: 输出管理器
"""
self.config_manager = config_manager
self.config = config_manager.get_config('poster', PosterConfig)
self.output_manager = output_manager
self.image_processor = ImageProcessor()
# 注册可用的模板
self.templates = {
"vibrant": VibrantTemplate,
"business": BusinessTemplate,
"collage": CollageTemplate,
}
def generate_poster(self, content: Dict[str, Any], topic_index: Union[int, str],
template_name: Optional[str] = None) -> Optional[str]:
"""
为指定内容生成海报
Args:
content: 内容数据,包含标题、正文等
topic_index: 主题索引,用于文件命名
template_name: 模板名称如果为None则根据配置选择
Returns:
生成的海报文件路径如果生成失败则返回None
"""
logger.info(f"开始为主题 {topic_index} 生成海报...")
# 1. 选择模板
if not template_name:
template_name = self._select_template()
if template_name not in self.templates:
logger.error(f"模板 '{template_name}' 不存在")
return None
template_class = self.templates[template_name]
template = template_class(self.config.target_size)
# 2. 准备内容
title = content.get('title', '')
text_content = content.get('content', '')
if not title or not text_content:
logger.error("内容缺少标题或正文")
return None
# 3. 生成海报
try:
poster_image = template.generate(title, text_content)
# 4. 保存海报
output_dir = self.output_manager.get_topic_dir(topic_index)
file_name = f"poster_{template_name}.png"
file_path = output_dir / file_name
poster_image.save(file_path)
logger.info(f"海报已保存到: {file_path}")
return str(file_path)
except Exception as e:
logger.error(f"生成海报时发生错误: {e}", exc_info=True)
return None
def _select_template(self) -> str:
"""根据配置选择模板"""
selection_method = self.config.template_selection
available_templates = self.config.available_templates
# 过滤出实际可用的模板
valid_templates = [t for t in available_templates if t in self.templates]
if not valid_templates:
logger.warning("没有可用的模板,使用默认模板")
return next(iter(self.templates.keys()))
if selection_method == "random":
return random.choice(valid_templates)
elif selection_method in valid_templates:
return selection_method
else:
logger.warning(f"无效的模板选择方法 '{selection_method}',使用随机选择")
return random.choice(valid_templates)