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

348 lines
21 KiB
JSON
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.

{
"file_path": "poster/templates/collage_template.py",
"file_size": 4095,
"line_count": 124,
"functions": [
{
"name": "generate",
"line_start": 24,
"line_end": 56,
"args": [
{
"name": "self"
},
{
"name": "image_paths",
"type_hint": "List[str]"
},
{
"name": "style",
"type_hint": "str"
}
],
"return_type": "Image.Image",
"docstring": "生成拼图海报\n\nArgs:\n image_paths (List[str]): 用于制作拼图的图片路径列表\n style (str): 拼图样式 (例如 'grid_2x2', 'asymmetric', 'filmstrip')\n\nReturns:\n Image.Image: 生成的拼图海报图像",
"is_async": false,
"decorators": [],
"code": " def generate(self,\n image_paths: List[str],\n style: str = 'grid_2x2',\n **kwargs) -> Image.Image:\n \"\"\"\n 生成拼图海报\n\n Args:\n image_paths (List[str]): 用于制作拼图的图片路径列表\n style (str): 拼图样式 (例如 'grid_2x2', 'asymmetric', 'filmstrip')\n \n Returns:\n Image.Image: 生成的拼图海报图像\n \"\"\"\n if not self._validate_inputs(['image_paths'], image_paths=image_paths):\n return None\n if not image_paths:\n logger.error(\"生成拼图失败: 图片列表不能为空。\")\n return None\n\n images = [self.image_processor.load_image(p) for p in image_paths if p]\n images = [img for img in images if img] # 过滤掉加载失败的图片\n\n if not images:\n logger.error(\"所有图片都加载失败。\")\n return None\n \n # 根据样式选择对应的私有方法\n style_method_name = f\"_create_{style}_collage\"\n style_method = getattr(self, style_method_name, self._create_grid_2x2_collage)\n \n logger.info(f\"使用 '{style}' 风格创建拼图...\")\n return style_method(images, self.size)",
"code_hash": "096ed2c4dad1d06302e309eee8b8fb27"
},
{
"name": "_resize_and_crop",
"line_start": 58,
"line_end": 60,
"args": [
{
"name": "self"
},
{
"name": "img"
},
{
"name": "target_size"
}
],
"return_type": null,
"docstring": "辅助方法:调整并裁剪图片以适应目标尺寸",
"is_async": false,
"decorators": [],
"code": " def _resize_and_crop(self, img, target_size):\n \"\"\"辅助方法:调整并裁剪图片以适应目标尺寸\"\"\"\n return self.image_processor.resize_and_crop(img, target_size)",
"code_hash": "696270183a17e54e5bcfae13e81b60c9"
},
{
"name": "_create_grid_2x2_collage",
"line_start": 64,
"line_end": 82,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Image.Image]"
},
{
"name": "target_size",
"type_hint": "Tuple[int, int]"
}
],
"return_type": "Image.Image",
"docstring": "创建 2x2 网格拼图",
"is_async": false,
"decorators": [],
"code": " def _create_grid_2x2_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建 2x2 网格拼图\"\"\"\n if len(images) < 4:\n logger.warning(f\"2x2网格需要4张图但只提供了{len(images)}张。将使用重复图片。\")\n images.extend([random.choice(images) for _ in range(4 - len(images))])\n \n w, h = target_size\n img_w, img_h = w // 2, h // 2\n \n canvas = self.create_canvas()\n \n resized_images = [self._resize_and_crop(img, (img_w, img_h)) for img in images[:4]]\n \n canvas.paste(resized_images[0], (0, 0))\n canvas.paste(resized_images[1], (img_w, 0))\n canvas.paste(resized_images[2], (0, img_h))\n canvas.paste(resized_images[3], (img_w, img_h))\n \n return canvas",
"code_hash": "82355b1196b092405dc327e4e7678a09"
},
{
"name": "_create_asymmetric_collage",
"line_start": 84,
"line_end": 105,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Image.Image]"
},
{
"name": "target_size",
"type_hint": "Tuple[int, int]"
}
],
"return_type": "Image.Image",
"docstring": "创建非对称拼图(左一右二)",
"is_async": false,
"decorators": [],
"code": " def _create_asymmetric_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建非对称拼图(左一右二)\"\"\"\n if len(images) < 3:\n logger.warning(f\"非对称拼图需要3张图将使用重复图片。\")\n images.extend([random.choice(images) for _ in range(3 - len(images))])\n \n w, h = target_size\n main_w = int(w * 0.6)\n side_w = w - main_w\n side_h = h // 2\n \n canvas = self.create_canvas()\n\n main_img = self._resize_and_crop(images[0], (main_w, h))\n side_img1 = self._resize_and_crop(images[1], (side_w, side_h))\n side_img2 = self._resize_and_crop(images[2], (side_w, side_h))\n \n canvas.paste(main_img, (0, 0))\n canvas.paste(side_img1, (main_w, 0))\n canvas.paste(side_img2, (main_w, side_h))\n\n return canvas",
"code_hash": "49917abd95156a55d639ba3a89c51208"
},
{
"name": "_create_filmstrip_collage",
"line_start": 107,
"line_end": 122,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Image.Image]"
},
{
"name": "target_size",
"type_hint": "Tuple[int, int]"
}
],
"return_type": "Image.Image",
"docstring": "创建电影胶片风格拼图",
"is_async": false,
"decorators": [],
"code": " def _create_filmstrip_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建电影胶片风格拼图\"\"\"\n num_images = min(len(images), 4) # 最多4张\n w, h = target_size\n padding = 10\n img_h = (h - (num_images + 1) * padding) // num_images\n\n canvas = self.create_canvas(background_color=(30, 30, 30, 255))\n \n current_y = padding\n for img in images[:num_images]:\n resized_img = self._resize_and_crop(img, (w - 2 * padding, img_h))\n canvas.paste(resized_img, (padding, current_y))\n current_y += img_h + padding\n \n return canvas",
"code_hash": "9ca7d505aaef9100103696bbfc71e660"
},
{
"name": "_validate_inputs",
"line_start": 124,
"line_end": 125,
"args": [
{
"name": "self"
},
{
"name": "required_keys",
"type_hint": "list"
}
],
"return_type": "bool",
"docstring": "",
"is_async": false,
"decorators": [],
"code": " def _validate_inputs(self, required_keys: list, **kwargs) -> bool:\n return super()._validate_inputs(required_keys, **kwargs) ",
"code_hash": "476143d3ed1432102ca95ee17d59b7bb"
}
],
"classes": [
{
"name": "CollageTemplate",
"line_start": 18,
"line_end": 125,
"bases": [
"BaseTemplate"
],
"methods": [
{
"name": "generate",
"line_start": 24,
"line_end": 56,
"args": [
{
"name": "self"
},
{
"name": "image_paths",
"type_hint": "List[str]"
},
{
"name": "style",
"type_hint": "str"
}
],
"return_type": "Image.Image",
"docstring": "生成拼图海报\n\nArgs:\n image_paths (List[str]): 用于制作拼图的图片路径列表\n style (str): 拼图样式 (例如 'grid_2x2', 'asymmetric', 'filmstrip')\n\nReturns:\n Image.Image: 生成的拼图海报图像",
"is_async": false,
"decorators": [],
"code": " def generate(self,\n image_paths: List[str],\n style: str = 'grid_2x2',\n **kwargs) -> Image.Image:\n \"\"\"\n 生成拼图海报\n\n Args:\n image_paths (List[str]): 用于制作拼图的图片路径列表\n style (str): 拼图样式 (例如 'grid_2x2', 'asymmetric', 'filmstrip')\n \n Returns:\n Image.Image: 生成的拼图海报图像\n \"\"\"\n if not self._validate_inputs(['image_paths'], image_paths=image_paths):\n return None\n if not image_paths:\n logger.error(\"生成拼图失败: 图片列表不能为空。\")\n return None\n\n images = [self.image_processor.load_image(p) for p in image_paths if p]\n images = [img for img in images if img] # 过滤掉加载失败的图片\n\n if not images:\n logger.error(\"所有图片都加载失败。\")\n return None\n \n # 根据样式选择对应的私有方法\n style_method_name = f\"_create_{style}_collage\"\n style_method = getattr(self, style_method_name, self._create_grid_2x2_collage)\n \n logger.info(f\"使用 '{style}' 风格创建拼图...\")\n return style_method(images, self.size)",
"code_hash": "096ed2c4dad1d06302e309eee8b8fb27"
},
{
"name": "_resize_and_crop",
"line_start": 58,
"line_end": 60,
"args": [
{
"name": "self"
},
{
"name": "img"
},
{
"name": "target_size"
}
],
"return_type": null,
"docstring": "辅助方法:调整并裁剪图片以适应目标尺寸",
"is_async": false,
"decorators": [],
"code": " def _resize_and_crop(self, img, target_size):\n \"\"\"辅助方法:调整并裁剪图片以适应目标尺寸\"\"\"\n return self.image_processor.resize_and_crop(img, target_size)",
"code_hash": "696270183a17e54e5bcfae13e81b60c9"
},
{
"name": "_create_grid_2x2_collage",
"line_start": 64,
"line_end": 82,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Image.Image]"
},
{
"name": "target_size",
"type_hint": "Tuple[int, int]"
}
],
"return_type": "Image.Image",
"docstring": "创建 2x2 网格拼图",
"is_async": false,
"decorators": [],
"code": " def _create_grid_2x2_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建 2x2 网格拼图\"\"\"\n if len(images) < 4:\n logger.warning(f\"2x2网格需要4张图但只提供了{len(images)}张。将使用重复图片。\")\n images.extend([random.choice(images) for _ in range(4 - len(images))])\n \n w, h = target_size\n img_w, img_h = w // 2, h // 2\n \n canvas = self.create_canvas()\n \n resized_images = [self._resize_and_crop(img, (img_w, img_h)) for img in images[:4]]\n \n canvas.paste(resized_images[0], (0, 0))\n canvas.paste(resized_images[1], (img_w, 0))\n canvas.paste(resized_images[2], (0, img_h))\n canvas.paste(resized_images[3], (img_w, img_h))\n \n return canvas",
"code_hash": "82355b1196b092405dc327e4e7678a09"
},
{
"name": "_create_asymmetric_collage",
"line_start": 84,
"line_end": 105,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Image.Image]"
},
{
"name": "target_size",
"type_hint": "Tuple[int, int]"
}
],
"return_type": "Image.Image",
"docstring": "创建非对称拼图(左一右二)",
"is_async": false,
"decorators": [],
"code": " def _create_asymmetric_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建非对称拼图(左一右二)\"\"\"\n if len(images) < 3:\n logger.warning(f\"非对称拼图需要3张图将使用重复图片。\")\n images.extend([random.choice(images) for _ in range(3 - len(images))])\n \n w, h = target_size\n main_w = int(w * 0.6)\n side_w = w - main_w\n side_h = h // 2\n \n canvas = self.create_canvas()\n\n main_img = self._resize_and_crop(images[0], (main_w, h))\n side_img1 = self._resize_and_crop(images[1], (side_w, side_h))\n side_img2 = self._resize_and_crop(images[2], (side_w, side_h))\n \n canvas.paste(main_img, (0, 0))\n canvas.paste(side_img1, (main_w, 0))\n canvas.paste(side_img2, (main_w, side_h))\n\n return canvas",
"code_hash": "49917abd95156a55d639ba3a89c51208"
},
{
"name": "_create_filmstrip_collage",
"line_start": 107,
"line_end": 122,
"args": [
{
"name": "self"
},
{
"name": "images",
"type_hint": "List[Image.Image]"
},
{
"name": "target_size",
"type_hint": "Tuple[int, int]"
}
],
"return_type": "Image.Image",
"docstring": "创建电影胶片风格拼图",
"is_async": false,
"decorators": [],
"code": " def _create_filmstrip_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建电影胶片风格拼图\"\"\"\n num_images = min(len(images), 4) # 最多4张\n w, h = target_size\n padding = 10\n img_h = (h - (num_images + 1) * padding) // num_images\n\n canvas = self.create_canvas(background_color=(30, 30, 30, 255))\n \n current_y = padding\n for img in images[:num_images]:\n resized_img = self._resize_and_crop(img, (w - 2 * padding, img_h))\n canvas.paste(resized_img, (padding, current_y))\n current_y += img_h + padding\n \n return canvas",
"code_hash": "9ca7d505aaef9100103696bbfc71e660"
},
{
"name": "_validate_inputs",
"line_start": 124,
"line_end": 125,
"args": [
{
"name": "self"
},
{
"name": "required_keys",
"type_hint": "list"
}
],
"return_type": "bool",
"docstring": "",
"is_async": false,
"decorators": [],
"code": " def _validate_inputs(self, required_keys: list, **kwargs) -> bool:\n return super()._validate_inputs(required_keys, **kwargs) ",
"code_hash": "476143d3ed1432102ca95ee17d59b7bb"
}
],
"docstring": "拼图风格模板,用于将多张图片组合成一张海报。\n支持多种布局样式如网格、非对称、电影胶片等。",
"decorators": [],
"code": "class CollageTemplate(BaseTemplate):\n \"\"\"\n 拼图风格模板,用于将多张图片组合成一张海报。\n 支持多种布局样式,如网格、非对称、电影胶片等。\n \"\"\"\n\n def generate(self,\n image_paths: List[str],\n style: str = 'grid_2x2',\n **kwargs) -> Image.Image:\n \"\"\"\n 生成拼图海报\n\n Args:\n image_paths (List[str]): 用于制作拼图的图片路径列表\n style (str): 拼图样式 (例如 'grid_2x2', 'asymmetric', 'filmstrip')\n \n Returns:\n Image.Image: 生成的拼图海报图像\n \"\"\"\n if not self._validate_inputs(['image_paths'], image_paths=image_paths):\n return None\n if not image_paths:\n logger.error(\"生成拼图失败: 图片列表不能为空。\")\n return None\n\n images = [self.image_processor.load_image(p) for p in image_paths if p]\n images = [img for img in images if img] # 过滤掉加载失败的图片\n\n if not images:\n logger.error(\"所有图片都加载失败。\")\n return None\n \n # 根据样式选择对应的私有方法\n style_method_name = f\"_create_{style}_collage\"\n style_method = getattr(self, style_method_name, self._create_grid_2x2_collage)\n \n logger.info(f\"使用 '{style}' 风格创建拼图...\")\n return style_method(images, self.size)\n\n def _resize_and_crop(self, img, target_size):\n \"\"\"辅助方法:调整并裁剪图片以适应目标尺寸\"\"\"\n return self.image_processor.resize_and_crop(img, target_size)\n\n # --- 各种拼图样式的实现 ---\n\n def _create_grid_2x2_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建 2x2 网格拼图\"\"\"\n if len(images) < 4:\n logger.warning(f\"2x2网格需要4张图但只提供了{len(images)}张。将使用重复图片。\")\n images.extend([random.choice(images) for _ in range(4 - len(images))])\n \n w, h = target_size\n img_w, img_h = w // 2, h // 2\n \n canvas = self.create_canvas()\n \n resized_images = [self._resize_and_crop(img, (img_w, img_h)) for img in images[:4]]\n \n canvas.paste(resized_images[0], (0, 0))\n canvas.paste(resized_images[1], (img_w, 0))\n canvas.paste(resized_images[2], (0, img_h))\n canvas.paste(resized_images[3], (img_w, img_h))\n \n return canvas\n\n def _create_asymmetric_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建非对称拼图(左一右二)\"\"\"\n if len(images) < 3:\n logger.warning(f\"非对称拼图需要3张图将使用重复图片。\")\n images.extend([random.choice(images) for _ in range(3 - len(images))])\n \n w, h = target_size\n main_w = int(w * 0.6)\n side_w = w - main_w\n side_h = h // 2\n \n canvas = self.create_canvas()\n\n main_img = self._resize_and_crop(images[0], (main_w, h))\n side_img1 = self._resize_and_crop(images[1], (side_w, side_h))\n side_img2 = self._resize_and_crop(images[2], (side_w, side_h))\n \n canvas.paste(main_img, (0, 0))\n canvas.paste(side_img1, (main_w, 0))\n canvas.paste(side_img2, (main_w, side_h))\n\n return canvas\n\n def _create_filmstrip_collage(self, images: List[Image.Image], target_size: Tuple[int, int]) -> Image.Image:\n \"\"\"创建电影胶片风格拼图\"\"\"\n num_images = min(len(images), 4) # 最多4张\n w, h = target_size\n padding = 10\n img_h = (h - (num_images + 1) * padding) // num_images\n\n canvas = self.create_canvas(background_color=(30, 30, 30, 255))\n \n current_y = padding\n for img in images[:num_images]:\n resized_img = self._resize_and_crop(img, (w - 2 * padding, img_h))\n canvas.paste(resized_img, (padding, current_y))\n current_y += img_h + padding\n \n return canvas\n \n def _validate_inputs(self, required_keys: list, **kwargs) -> bool:\n return super()._validate_inputs(required_keys, **kwargs) ",
"code_hash": "2bc0edfc12a8ceeab12e40988b8dcfca"
}
],
"imports": [
{
"type": "import",
"modules": [
"logging"
],
"aliases": []
},
{
"type": "import",
"modules": [
"random"
],
"aliases": []
},
{
"type": "from_import",
"module": "typing",
"names": [
"List",
"Tuple",
"Optional"
],
"aliases": [],
"level": 0
},
{
"type": "from_import",
"module": "PIL",
"names": [
"Image",
"ImageDraw"
],
"aliases": [],
"level": 0
},
{
"type": "from_import",
"module": "base_template",
"names": [
"BaseTemplate"
],
"aliases": [],
"level": 1
}
],
"constants": [],
"docstring": "Collage风格拼图风格海报模板",
"content_hash": "b04aa331f67aa2626fee2d7665fbf690"
}