2025-07-31 15:35:23 +08:00

473 lines
38 KiB
JSON
Raw Permalink 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.

{
"file_path": "travel-algorithms/travel_algorithms/poster_generation/poster_generator.py",
"file_size": 10262,
"line_count": 312,
"functions": [
{
"name": "__init__",
"line_start": 30,
"line_end": 55,
"args": [
{
"name": "self"
},
{
"name": "config",
"type_hint": "AlgorithmConfig"
}
],
"return_type": null,
"docstring": "初始化海报生成器\n\nArgs:\n config: 算法配置",
"is_async": false,
"decorators": [],
"code": " def __init__(self, config: AlgorithmConfig):\n \"\"\"\n 初始化海报生成器\n\n Args:\n config: 算法配置\n \"\"\"\n self.config = config\n self.ai_service = AIService(config.ai_model)\n self.output_manager = OutputManager(config.output)\n self.prompt_manager = PromptManager(config.prompts, config.resources)\n \n # 初始化JSON处理器\n self.json_processor = JSONProcessor(\n enable_repair=config.content_generation.enable_json_repair,\n max_repair_attempts=config.content_generation.json_repair_attempts\n )\n \n # 初始化模板管理器和文本生成器\n self.template_manager = TemplateManager(config.poster_generation, config.resources)\n self.text_generator = TextGenerator(config, self.ai_service, self.prompt_manager, self.json_processor)\n \n # 获取任务特定的模型配置\n self.task_model_config = config.ai_model.get_task_config(\"poster_generation\")\n \n logger.info(f\"海报生成器初始化完成,可用模板: {self.template_manager.get_available_templates()}\")",
"code_hash": "a743516f147a9907773be701378e817e"
},
{
"name": "_process_images",
"line_start": 167,
"line_end": 191,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Union[str, Image.Image]]"
}
],
"return_type": "List[Image.Image]",
"docstring": "预处理图像列表",
"is_async": false,
"decorators": [],
"code": " def _process_images(self, images: List[Union[str, Image.Image]]) -> List[Image.Image]:\n \"\"\"预处理图像列表\"\"\"\n processed_images = []\n \n for img in images:\n try:\n if isinstance(img, str):\n # 从路径加载图像\n img_path = Path(img)\n if img_path.exists():\n pil_image = Image.open(img_path)\n processed_images.append(pil_image.convert(\"RGB\"))\n else:\n logger.warning(f\"图像文件不存在: {img_path}\")\n elif isinstance(img, Image.Image):\n # 直接使用PIL图像\n processed_images.append(img.convert(\"RGB\"))\n else:\n logger.warning(f\"不支持的图像类型: {type(img)}\")\n \n except Exception as e:\n logger.error(f\"处理图像失败: {e}\")\n continue\n \n return processed_images",
"code_hash": "143b89e4f27f57ba8e2a3640aee951da"
},
{
"name": "_merge_style_options",
"line_start": 193,
"line_end": 219,
"args": [
{
"name": "self"
},
{
"name": "style_options",
"type_hint": "Optional[Dict[str, Any]]"
},
{
"name": "kwargs",
"type_hint": "Dict[str, Any]"
}
],
"return_type": "Dict[str, Any]",
"docstring": "合并样式选项",
"is_async": false,
"decorators": [],
"code": " def _merge_style_options(\n self, \n style_options: Optional[Dict[str, Any]], \n kwargs: Dict[str, Any]\n ) -> Dict[str, Any]:\n \"\"\"合并样式选项\"\"\"\n \n # 从配置获取默认选项\n default_options = {\n \"size\": self.config.poster_generation.default_size,\n \"color_themes\": self.config.poster_generation.color_themes,\n \"font_configs\": self.config.poster_generation.font_configs,\n \"glass_effect\": self.config.poster_generation.glass_effect,\n \"text_effects\": self.config.poster_generation.text_effects\n }\n \n # 合并用户提供的选项\n merged_options = default_options.copy()\n if style_options:\n merged_options.update(style_options)\n \n # 合并kwargs中的选项\n poster_related_kwargs = {k: v for k, v in kwargs.items() \n if k in [\"theme_color\", \"glass_intensity\", \"num_variations\", \"font_size\"]}\n merged_options.update(poster_related_kwargs)\n \n return merged_options",
"code_hash": "92c854ceb9e3ff2fa89890a950bcae18"
},
{
"name": "_get_default_content",
"line_start": 221,
"line_end": 228,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "获取默认海报内容",
"is_async": false,
"decorators": [],
"code": " def _get_default_content(self) -> Dict[str, Any]:\n \"\"\"获取默认海报内容\"\"\"\n return {\n \"title\": \"探索美景\",\n \"content\": \"发现世界的美好,记录旅途的精彩瞬间。\",\n \"tags\": [\"旅游\", \"美景\", \"探索\"],\n \"call_to_action\": \"立即出发\"\n }",
"code_hash": "33437206afdbafb58c772e5b5cebebd5"
},
{
"name": "get_available_templates",
"line_start": 267,
"line_end": 269,
"args": [
{
"name": "self"
}
],
"return_type": "List[str]",
"docstring": "获取可用的模板列表",
"is_async": false,
"decorators": [],
"code": " def get_available_templates(self) -> List[str]:\n \"\"\"获取可用的模板列表\"\"\"\n return self.template_manager.get_available_templates()",
"code_hash": "e8378fae7f8f67b773905c38390725cb"
},
{
"name": "get_template_info",
"line_start": 271,
"line_end": 273,
"args": [
{
"name": "self"
},
{
"name": "template_name",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "获取模板信息",
"is_async": false,
"decorators": [],
"code": " def get_template_info(self, template_name: str) -> Dict[str, Any]:\n \"\"\"获取模板信息\"\"\"\n return self.template_manager.get_template_info(template_name)",
"code_hash": "0512927eaf10ea632edbd9edb0e874c2"
},
{
"name": "get_generation_stats",
"line_start": 298,
"line_end": 313,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "获取生成统计信息\n\nReturns:\n 统计信息字典",
"is_async": false,
"decorators": [],
"code": " def get_generation_stats(self) -> Dict[str, Any]:\n \"\"\"\n 获取生成统计信息\n\n Returns:\n 统计信息字典\n \"\"\"\n return {\n \"task_model_config\": self.task_model_config,\n \"available_templates\": self.get_available_templates(),\n \"default_size\": self.config.poster_generation.default_size,\n \"color_themes\": list(self.config.poster_generation.color_themes.keys()),\n \"output_directory\": str(self.output_manager.run_output_dir),\n \"ai_model_info\": self.ai_service.get_model_info(),\n \"template_manager_info\": self.template_manager.get_manager_info()\n } ",
"code_hash": "99540bf3941805e02cf565387f898688"
}
],
"classes": [
{
"name": "PosterGenerator",
"line_start": 24,
"line_end": 313,
"bases": [],
"methods": [
{
"name": "__init__",
"line_start": 30,
"line_end": 55,
"args": [
{
"name": "self"
},
{
"name": "config",
"type_hint": "AlgorithmConfig"
}
],
"return_type": null,
"docstring": "初始化海报生成器\n\nArgs:\n config: 算法配置",
"is_async": false,
"decorators": [],
"code": " def __init__(self, config: AlgorithmConfig):\n \"\"\"\n 初始化海报生成器\n\n Args:\n config: 算法配置\n \"\"\"\n self.config = config\n self.ai_service = AIService(config.ai_model)\n self.output_manager = OutputManager(config.output)\n self.prompt_manager = PromptManager(config.prompts, config.resources)\n \n # 初始化JSON处理器\n self.json_processor = JSONProcessor(\n enable_repair=config.content_generation.enable_json_repair,\n max_repair_attempts=config.content_generation.json_repair_attempts\n )\n \n # 初始化模板管理器和文本生成器\n self.template_manager = TemplateManager(config.poster_generation, config.resources)\n self.text_generator = TextGenerator(config, self.ai_service, self.prompt_manager, self.json_processor)\n \n # 获取任务特定的模型配置\n self.task_model_config = config.ai_model.get_task_config(\"poster_generation\")\n \n logger.info(f\"海报生成器初始化完成,可用模板: {self.template_manager.get_available_templates()}\")",
"code_hash": "a743516f147a9907773be701378e817e"
},
{
"name": "generate_poster",
"line_start": 57,
"line_end": 147,
"args": [
{
"name": "self"
},
{
"name": "content",
"type_hint": "Optional[Dict[str, Any]]"
},
{
"name": "images",
"type_hint": "Optional[List[Union[str, Image.Image]]]"
},
{
"name": "template_name",
"type_hint": "str"
},
{
"name": "style_options",
"type_hint": "Optional[Dict[str, Any]]"
}
],
"return_type": "Tuple[str, Dict[str, Any]]",
"docstring": "生成海报\n\nArgs:\n content: 海报文本内容如果为空将使用AI生成\n images: 图像列表文件路径或PIL图像对象\n template_name: 模板名称\n style_options: 样式选项\n **kwargs: 其他参数\n\nReturns:\n Tuple[请求ID, 生成结果]\n\nRaises:\n PosterGenerationError: 生成失败时抛出",
"is_async": true,
"decorators": [],
"code": " async def generate_poster(\n self,\n content: Optional[Dict[str, Any]] = None,\n images: Optional[List[Union[str, Image.Image]]] = None,\n template_name: str = \"vibrant\",\n style_options: Optional[Dict[str, Any]] = None,\n **kwargs\n ) -> Tuple[str, Dict[str, Any]]:\n \"\"\"\n 生成海报\n\n Args:\n content: 海报文本内容如果为空将使用AI生成\n images: 图像列表文件路径或PIL图像对象\n template_name: 模板名称\n style_options: 样式选项\n **kwargs: 其他参数\n\n Returns:\n Tuple[请求ID, 生成结果]\n\n Raises:\n PosterGenerationError: 生成失败时抛出\n \"\"\"\n try:\n logger.info(f\"开始生成海报,模板: {template_name}\")\n\n # 1. 如果没有提供内容使用AI生成\n if not content:\n content = await self._generate_poster_content(**kwargs)\n\n # 2. 预处理图像\n processed_images = self._process_images(images or [])\n \n if not processed_images:\n raise PosterGenerationError(\"未提供有效的图像\")\n\n # 3. 获取模板并生成海报\n template = self.template_manager.get_template(template_name)\n \n # 合并样式选项\n generation_options = self._merge_style_options(style_options, kwargs)\n \n # 生成海报\n poster_image = template.generate(\n images=processed_images,\n content=content,\n **generation_options\n )\n\n if not poster_image:\n raise PosterGenerationError(\"模板生成海报失败\")\n\n # 4. 保存海报\n poster_path = self.output_manager.save_image(poster_image, \"poster\")\n\n # 5. 保存生成配置和内容\n generation_data = {\n \"template_name\": template_name,\n \"content\": content,\n \"style_options\": style_options,\n \"generation_options\": generation_options,\n \"poster_path\": poster_path,\n \"image_count\": len(processed_images),\n \"poster_size\": poster_image.size,\n \"template_config\": template.get_config(),\n \"metadata\": {\n \"model_config\": self.task_model_config,\n \"generated_at\": self.output_manager.run_id\n }\n }\n\n self.output_manager.save_json(generation_data, \"poster_data\")\n\n # 6. 保存元数据\n metadata = {\n \"template_name\": template_name,\n \"content_word_count\": len(content.get(\"content\", \"\")),\n \"model_config\": self.task_model_config,\n \"poster_config\": self.config.poster_generation.dict(),\n \"generation_options\": generation_options\n }\n self.output_manager.save_metadata(metadata, \"poster_generation\")\n\n logger.info(f\"海报生成完成,保存路径: {poster_path}\")\n return self.output_manager.run_id, generation_data\n\n except Exception as e:\n error_msg = f\"海报生成失败: {str(e)}\"\n logger.error(error_msg, exc_info=True)\n raise PosterGenerationError(error_msg)",
"code_hash": "6dc30d8138189f09110d9bf70000f69b"
},
{
"name": "_generate_poster_content",
"line_start": 149,
"line_end": 165,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "使用AI生成海报内容",
"is_async": true,
"decorators": [],
"code": " async def _generate_poster_content(self, **kwargs) -> Dict[str, Any]:\n \"\"\"使用AI生成海报内容\"\"\"\n try:\n topic_info = kwargs.get(\"topic_info\", \"旅游景点推荐\")\n style = kwargs.get(\"content_style\", \"活泼有趣\")\n \n content = await self.text_generator.generate_poster_content(\n topic_info=topic_info,\n style=style,\n **kwargs\n )\n \n return content\n \n except Exception as e:\n logger.warning(f\"AI生成海报内容失败使用默认内容: {e}\")\n return self._get_default_content()",
"code_hash": "3e4a86c5445ff5d8a2d8de8b950d6625"
},
{
"name": "_process_images",
"line_start": 167,
"line_end": 191,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Union[str, Image.Image]]"
}
],
"return_type": "List[Image.Image]",
"docstring": "预处理图像列表",
"is_async": false,
"decorators": [],
"code": " def _process_images(self, images: List[Union[str, Image.Image]]) -> List[Image.Image]:\n \"\"\"预处理图像列表\"\"\"\n processed_images = []\n \n for img in images:\n try:\n if isinstance(img, str):\n # 从路径加载图像\n img_path = Path(img)\n if img_path.exists():\n pil_image = Image.open(img_path)\n processed_images.append(pil_image.convert(\"RGB\"))\n else:\n logger.warning(f\"图像文件不存在: {img_path}\")\n elif isinstance(img, Image.Image):\n # 直接使用PIL图像\n processed_images.append(img.convert(\"RGB\"))\n else:\n logger.warning(f\"不支持的图像类型: {type(img)}\")\n \n except Exception as e:\n logger.error(f\"处理图像失败: {e}\")\n continue\n \n return processed_images",
"code_hash": "143b89e4f27f57ba8e2a3640aee951da"
},
{
"name": "_merge_style_options",
"line_start": 193,
"line_end": 219,
"args": [
{
"name": "self"
},
{
"name": "style_options",
"type_hint": "Optional[Dict[str, Any]]"
},
{
"name": "kwargs",
"type_hint": "Dict[str, Any]"
}
],
"return_type": "Dict[str, Any]",
"docstring": "合并样式选项",
"is_async": false,
"decorators": [],
"code": " def _merge_style_options(\n self, \n style_options: Optional[Dict[str, Any]], \n kwargs: Dict[str, Any]\n ) -> Dict[str, Any]:\n \"\"\"合并样式选项\"\"\"\n \n # 从配置获取默认选项\n default_options = {\n \"size\": self.config.poster_generation.default_size,\n \"color_themes\": self.config.poster_generation.color_themes,\n \"font_configs\": self.config.poster_generation.font_configs,\n \"glass_effect\": self.config.poster_generation.glass_effect,\n \"text_effects\": self.config.poster_generation.text_effects\n }\n \n # 合并用户提供的选项\n merged_options = default_options.copy()\n if style_options:\n merged_options.update(style_options)\n \n # 合并kwargs中的选项\n poster_related_kwargs = {k: v for k, v in kwargs.items() \n if k in [\"theme_color\", \"glass_intensity\", \"num_variations\", \"font_size\"]}\n merged_options.update(poster_related_kwargs)\n \n return merged_options",
"code_hash": "92c854ceb9e3ff2fa89890a950bcae18"
},
{
"name": "_get_default_content",
"line_start": 221,
"line_end": 228,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "获取默认海报内容",
"is_async": false,
"decorators": [],
"code": " def _get_default_content(self) -> Dict[str, Any]:\n \"\"\"获取默认海报内容\"\"\"\n return {\n \"title\": \"探索美景\",\n \"content\": \"发现世界的美好,记录旅途的精彩瞬间。\",\n \"tags\": [\"旅游\", \"美景\", \"探索\"],\n \"call_to_action\": \"立即出发\"\n }",
"code_hash": "33437206afdbafb58c772e5b5cebebd5"
},
{
"name": "generate_poster_batch",
"line_start": 230,
"line_end": 265,
"args": [
{
"name": "self"
},
{
"name": "content_list",
"type_hint": "List[Dict[str, Any]]"
},
{
"name": "template_name",
"type_hint": "str"
}
],
"return_type": "Dict[str, Dict[str, Any]]",
"docstring": "批量生成海报\n\nArgs:\n content_list: 内容列表\n template_name: 模板名称\n **kwargs: 其他参数\n\nReturns:\n 批次ID->海报数据的字典",
"is_async": true,
"decorators": [],
"code": " async def generate_poster_batch(\n self,\n content_list: List[Dict[str, Any]],\n template_name: str = \"vibrant\",\n **kwargs\n ) -> Dict[str, Dict[str, Any]]:\n \"\"\"\n 批量生成海报\n\n Args:\n content_list: 内容列表\n template_name: 模板名称\n **kwargs: 其他参数\n\n Returns:\n 批次ID->海报数据的字典\n \"\"\"\n results = {}\n \n for i, content in enumerate(content_list):\n try:\n logger.info(f\"批量生成海报 {i+1}/{len(content_list)}\")\n \n request_id, poster_data = await self.generate_poster(\n content=content,\n template_name=template_name,\n **kwargs\n )\n \n results[f\"poster_{i+1}\"] = poster_data\n \n except Exception as e:\n logger.error(f\"批量生成第 {i+1} 项失败: {e}\")\n results[f\"poster_{i+1}\"] = {\"error\": str(e)}\n \n return results",
"code_hash": "21d9f2826515831121739003d4e7a3eb"
},
{
"name": "get_available_templates",
"line_start": 267,
"line_end": 269,
"args": [
{
"name": "self"
}
],
"return_type": "List[str]",
"docstring": "获取可用的模板列表",
"is_async": false,
"decorators": [],
"code": " def get_available_templates(self) -> List[str]:\n \"\"\"获取可用的模板列表\"\"\"\n return self.template_manager.get_available_templates()",
"code_hash": "e8378fae7f8f67b773905c38390725cb"
},
{
"name": "get_template_info",
"line_start": 271,
"line_end": 273,
"args": [
{
"name": "self"
},
{
"name": "template_name",
"type_hint": "str"
}
],
"return_type": "Dict[str, Any]",
"docstring": "获取模板信息",
"is_async": false,
"decorators": [],
"code": " def get_template_info(self, template_name: str) -> Dict[str, Any]:\n \"\"\"获取模板信息\"\"\"\n return self.template_manager.get_template_info(template_name)",
"code_hash": "0512927eaf10ea632edbd9edb0e874c2"
},
{
"name": "test_generation",
"line_start": 275,
"line_end": 296,
"args": [
{
"name": "self"
}
],
"return_type": "bool",
"docstring": "测试海报生成功能\n\nReturns:\n 测试是否成功",
"is_async": true,
"decorators": [],
"code": " async def test_generation(self) -> bool:\n \"\"\"\n 测试海报生成功能\n\n Returns:\n 测试是否成功\n \"\"\"\n try:\n # 创建测试图像\n test_image = Image.new(\"RGB\", (400, 300), color=\"lightblue\")\n \n _, poster_data = await self.generate_poster(\n content=self._get_default_content(),\n images=[test_image],\n template_name=\"vibrant\"\n )\n \n return \"poster_path\" in poster_data\n \n except Exception as e:\n logger.error(f\"海报生成测试失败: {e}\")\n return False",
"code_hash": "293ab7696ec10580dbaefb92d3ebaa3f"
},
{
"name": "get_generation_stats",
"line_start": 298,
"line_end": 313,
"args": [
{
"name": "self"
}
],
"return_type": "Dict[str, Any]",
"docstring": "获取生成统计信息\n\nReturns:\n 统计信息字典",
"is_async": false,
"decorators": [],
"code": " def get_generation_stats(self) -> Dict[str, Any]:\n \"\"\"\n 获取生成统计信息\n\n Returns:\n 统计信息字典\n \"\"\"\n return {\n \"task_model_config\": self.task_model_config,\n \"available_templates\": self.get_available_templates(),\n \"default_size\": self.config.poster_generation.default_size,\n \"color_themes\": list(self.config.poster_generation.color_themes.keys()),\n \"output_directory\": str(self.output_manager.run_output_dir),\n \"ai_model_info\": self.ai_service.get_model_info(),\n \"template_manager_info\": self.template_manager.get_manager_info()\n } ",
"code_hash": "99540bf3941805e02cf565387f898688"
}
],
"docstring": "海报生成器 - 重构版本\n负责根据文本内容和配置生成海报图像支持多种模板和风格",
"decorators": [],
"code": "class PosterGenerator:\n \"\"\"\n 海报生成器 - 重构版本\n 负责根据文本内容和配置生成海报图像,支持多种模板和风格\n \"\"\"\n\n def __init__(self, config: AlgorithmConfig):\n \"\"\"\n 初始化海报生成器\n\n Args:\n config: 算法配置\n \"\"\"\n self.config = config\n self.ai_service = AIService(config.ai_model)\n self.output_manager = OutputManager(config.output)\n self.prompt_manager = PromptManager(config.prompts, config.resources)\n \n # 初始化JSON处理器\n self.json_processor = JSONProcessor(\n enable_repair=config.content_generation.enable_json_repair,\n max_repair_attempts=config.content_generation.json_repair_attempts\n )\n \n # 初始化模板管理器和文本生成器\n self.template_manager = TemplateManager(config.poster_generation, config.resources)\n self.text_generator = TextGenerator(config, self.ai_service, self.prompt_manager, self.json_processor)\n \n # 获取任务特定的模型配置\n self.task_model_config = config.ai_model.get_task_config(\"poster_generation\")\n \n logger.info(f\"海报生成器初始化完成,可用模板: {self.template_manager.get_available_templates()}\")\n\n async def generate_poster(\n self,\n content: Optional[Dict[str, Any]] = None,\n images: Optional[List[Union[str, Image.Image]]] = None,\n template_name: str = \"vibrant\",\n style_options: Optional[Dict[str, Any]] = None,\n **kwargs\n ) -> Tuple[str, Dict[str, Any]]:\n \"\"\"\n 生成海报\n\n Args:\n content: 海报文本内容如果为空将使用AI生成\n images: 图像列表文件路径或PIL图像对象\n template_name: 模板名称\n style_options: 样式选项\n **kwargs: 其他参数\n\n Returns:\n Tuple[请求ID, 生成结果]\n\n Raises:\n PosterGenerationError: 生成失败时抛出\n \"\"\"\n try:\n logger.info(f\"开始生成海报,模板: {template_name}\")\n\n # 1. 如果没有提供内容使用AI生成\n if not content:\n content = await self._generate_poster_content(**kwargs)\n\n # 2. 预处理图像\n processed_images = self._process_images(images or [])\n \n if not processed_images:\n raise PosterGenerationError(\"未提供有效的图像\")\n\n # 3. 获取模板并生成海报\n template = self.template_manager.get_template(template_name)\n \n # 合并样式选项\n generation_options = self._merge_style_options(style_options, kwargs)\n \n # 生成海报\n poster_image = template.generate(\n images=processed_images,\n content=content,\n **generation_options\n )\n\n if not poster_image:\n raise PosterGenerationError(\"模板生成海报失败\")\n\n # 4. 保存海报\n poster_path = self.output_manager.save_image(poster_image, \"poster\")\n\n # 5. 保存生成配置和内容\n generation_data = {\n \"template_name\": template_name,\n \"content\": content,\n \"style_options\": style_options,\n \"generation_options\": generation_options,\n \"poster_path\": poster_path,\n \"image_count\": len(processed_images),\n \"poster_size\": poster_image.size,\n \"template_config\": template.get_config(),\n \"metadata\": {\n \"model_config\": self.task_model_config,\n \"generated_at\": self.output_manager.run_id\n }\n }\n\n self.output_manager.save_json(generation_data, \"poster_data\")\n\n # 6. 保存元数据\n metadata = {\n \"template_name\": template_name,\n \"content_word_count\": len(content.get(\"content\", \"\")),\n \"model_config\": self.task_model_config,\n \"poster_config\": self.config.poster_generation.dict(),\n \"generation_options\": generation_options\n }\n self.output_manager.save_metadata(metadata, \"poster_generation\")\n\n logger.info(f\"海报生成完成,保存路径: {poster_path}\")\n return self.output_manager.run_id, generation_data\n\n except Exception as e:\n error_msg = f\"海报生成失败: {str(e)}\"\n logger.error(error_msg, exc_info=True)\n raise PosterGenerationError(error_msg)\n\n async def _generate_poster_content(self, **kwargs) -> Dict[str, Any]:\n \"\"\"使用AI生成海报内容\"\"\"\n try:\n topic_info = kwargs.get(\"topic_info\", \"旅游景点推荐\")\n style = kwargs.get(\"content_style\", \"活泼有趣\")\n \n content = await self.text_generator.generate_poster_content(\n topic_info=topic_info,\n style=style,\n **kwargs\n )\n \n return content\n \n except Exception as e:\n logger.warning(f\"AI生成海报内容失败使用默认内容: {e}\")\n return self._get_default_content()\n\n def _process_images(self, images: List[Union[str, Image.Image]]) -> List[Image.Image]:\n \"\"\"预处理图像列表\"\"\"\n processed_images = []\n \n for img in images:\n try:\n if isinstance(img, str):\n # 从路径加载图像\n img_path = Path(img)\n if img_path.exists():\n pil_image = Image.open(img_path)\n processed_images.append(pil_image.convert(\"RGB\"))\n else:\n logger.warning(f\"图像文件不存在: {img_path}\")\n elif isinstance(img, Image.Image):\n # 直接使用PIL图像\n processed_images.append(img.convert(\"RGB\"))\n else:\n logger.warning(f\"不支持的图像类型: {type(img)}\")\n \n except Exception as e:\n logger.error(f\"处理图像失败: {e}\")\n continue\n \n return processed_images\n\n def _merge_style_options(\n self, \n style_options: Optional[Dict[str, Any]], \n kwargs: Dict[str, Any]\n ) -> Dict[str, Any]:\n \"\"\"合并样式选项\"\"\"\n \n # 从配置获取默认选项\n default_options = {\n \"size\": self.config.poster_generation.default_size,\n \"color_themes\": self.config.poster_generation.color_themes,\n \"font_configs\": self.config.poster_generation.font_configs,\n \"glass_effect\": self.config.poster_generation.glass_effect,\n \"text_effects\": self.config.poster_generation.text_effects\n }\n \n # 合并用户提供的选项\n merged_options = default_options.copy()\n if style_options:\n merged_options.update(style_options)\n \n # 合并kwargs中的选项\n poster_related_kwargs = {k: v for k, v in kwargs.items() \n if k in [\"theme_color\", \"glass_intensity\", \"num_variations\", \"font_size\"]}\n merged_options.update(poster_related_kwargs)\n \n return merged_options\n\n def _get_default_content(self) -> Dict[str, Any]:\n \"\"\"获取默认海报内容\"\"\"\n return {\n \"title\": \"探索美景\",\n \"content\": \"发现世界的美好,记录旅途的精彩瞬间。\",\n \"tags\": [\"旅游\", \"美景\", \"探索\"],\n \"call_to_action\": \"立即出发\"\n }\n\n async def generate_poster_batch(\n self,\n content_list: List[Dict[str, Any]],\n template_name: str = \"vibrant\",\n **kwargs\n ) -> Dict[str, Dict[str, Any]]:\n \"\"\"\n 批量生成海报\n\n Args:\n content_list: 内容列表\n template_name: 模板名称\n **kwargs: 其他参数\n\n Returns:\n 批次ID->海报数据的字典\n \"\"\"\n results = {}\n \n for i, content in enumerate(content_list):\n try:\n logger.info(f\"批量生成海报 {i+1}/{len(content_list)}\")\n \n request_id, poster_data = await self.generate_poster(\n content=content,\n template_name=template_name,\n **kwargs\n )\n \n results[f\"poster_{i+1}\"] = poster_data\n \n except Exception as e:\n logger.error(f\"批量生成第 {i+1} 项失败: {e}\")\n results[f\"poster_{i+1}\"] = {\"error\": str(e)}\n \n return results\n\n def get_available_templates(self) -> List[str]:\n \"\"\"获取可用的模板列表\"\"\"\n return self.template_manager.get_available_templates()\n\n def get_template_info(self, template_name: str) -> Dict[str, Any]:\n \"\"\"获取模板信息\"\"\"\n return self.template_manager.get_template_info(template_name)\n\n async def test_generation(self) -> bool:\n \"\"\"\n 测试海报生成功能\n\n Returns:\n 测试是否成功\n \"\"\"\n try:\n # 创建测试图像\n test_image = Image.new(\"RGB\", (400, 300), color=\"lightblue\")\n \n _, poster_data = await self.generate_poster(\n content=self._get_default_content(),\n images=[test_image],\n template_name=\"vibrant\"\n )\n \n return \"poster_path\" in poster_data\n \n except Exception as e:\n logger.error(f\"海报生成测试失败: {e}\")\n return False\n\n def get_generation_stats(self) -> Dict[str, Any]:\n \"\"\"\n 获取生成统计信息\n\n Returns:\n 统计信息字典\n \"\"\"\n return {\n \"task_model_config\": self.task_model_config,\n \"available_templates\": self.get_available_templates(),\n \"default_size\": self.config.poster_generation.default_size,\n \"color_themes\": list(self.config.poster_generation.color_themes.keys()),\n \"output_directory\": str(self.output_manager.run_output_dir),\n \"ai_model_info\": self.ai_service.get_model_info(),\n \"template_manager_info\": self.template_manager.get_manager_info()\n } ",
"code_hash": "f5fc6dd4c71195b2a38ef9313d6ee9e8"
}
],
"imports": [
{
"type": "import",
"modules": [
"logging"
],
"aliases": []
},
{
"type": "import",
"modules": [
"random"
],
"aliases": []
},
{
"type": "from_import",
"module": "typing",
"names": [
"List",
"Dict",
"Any",
"Optional",
"Union",
"Tuple"
],
"aliases": [],
"level": 0
},
{
"type": "from_import",
"module": "pathlib",
"names": [
"Path"
],
"aliases": [],
"level": 0
},
{
"type": "from_import",
"module": "PIL",
"names": [
"Image"
],
"aliases": [],
"level": 0
},
{
"type": "from_import",
"module": "config",
"names": [
"AlgorithmConfig"
],
"aliases": [],
"level": 2
},
{
"type": "from_import",
"module": "core",
"names": [
"AIService",
"OutputManager",
"PromptManager",
"JSONProcessor"
],
"aliases": [],
"level": 2
},
{
"type": "from_import",
"module": "exceptions",
"names": [
"PosterGenerationError",
"ResourceNotFoundError"
],
"aliases": [],
"level": 2
},
{
"type": "from_import",
"module": "template_manager",
"names": [
"TemplateManager"
],
"aliases": [],
"level": 1
},
{
"type": "from_import",
"module": "text_generator",
"names": [
"TextGenerator"
],
"aliases": [],
"level": 1
}
],
"constants": [],
"docstring": "Poster Generator\n海报生成器 - 重构版本,使用配置化系统和动态模板加载",
"content_hash": "bf0f8dd872f37b7f08bcc2deb28b08be"
}