473 lines
38 KiB
JSON
473 lines
38 KiB
JSON
{
|
||
"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"
|
||
} |