diff --git a/core/__pycache__/__init__.cpython-312.pyc b/core/__pycache__/__init__.cpython-312.pyc index 3ce90a8..c040350 100644 Binary files a/core/__pycache__/__init__.cpython-312.pyc and b/core/__pycache__/__init__.cpython-312.pyc differ diff --git a/core/__pycache__/ai_agent.cpython-312.pyc b/core/__pycache__/ai_agent.cpython-312.pyc index ddbb6ba..dae3bf4 100644 Binary files a/core/__pycache__/ai_agent.cpython-312.pyc and b/core/__pycache__/ai_agent.cpython-312.pyc differ diff --git a/core/__pycache__/poster_gen.cpython-312.pyc b/core/__pycache__/poster_gen.cpython-312.pyc index fcd33a3..18f2c48 100644 Binary files a/core/__pycache__/poster_gen.cpython-312.pyc and b/core/__pycache__/poster_gen.cpython-312.pyc differ diff --git a/core/__pycache__/simple_collage.cpython-312.pyc b/core/__pycache__/simple_collage.cpython-312.pyc index 82c1e67..f3a325b 100644 Binary files a/core/__pycache__/simple_collage.cpython-312.pyc and b/core/__pycache__/simple_collage.cpython-312.pyc differ diff --git a/core/__pycache__/topic_parser.cpython-312.pyc b/core/__pycache__/topic_parser.cpython-312.pyc index e943c02..89dd363 100644 Binary files a/core/__pycache__/topic_parser.cpython-312.pyc and b/core/__pycache__/topic_parser.cpython-312.pyc differ diff --git a/core/simple_collage.py b/core/simple_collage.py index 4892f7d..19955a6 100644 --- a/core/simple_collage.py +++ b/core/simple_collage.py @@ -6,11 +6,14 @@ import math from pathlib import Path from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageOps import logging # Import logging module +import re class ImageCollageCreator: def __init__(self, ): """初始化拼图创建器""" - + self.collage_style = None + self.created_collages = [] + # 定义可用拼接样式 self.collage_styles = [ "grid_2x2", # 标准2x2网格 @@ -133,33 +136,121 @@ class ImageCollageCreator: print(f"增强图片效果时出错: {str(e)}") return img - def create_collage_with_style(self, input_dir, style=None, target_size=None): - """创建指定样式的拼接画布 - - 参数: - input_dir: 输入图片目录路径 - style: 拼贴样式,如不指定则随机选择 - target_size: 目标尺寸,默认为(900, 1200) - - 返回: - tuple: (拼贴图, 选择的图片名称列表),如果创建失败则返回(None, []) + def find_directory_fuzzy_match(self, base_dir, target_name): """ - logging.info(f"--- Starting Collage Creation for Directory: {input_dir} ---") # Start Log + 对图片目录进行模糊匹配,查找最匹配目标名称的目录 + + Args: + base_dir: 基础目录路径 + target_name: 目标对象名称 + + Returns: + tuple: (最佳匹配目录路径, 匹配分数) 如果没有匹配则返回 (None, 0) + """ + logging.info(f"尝试对图片目录进行模糊匹配: {target_name}") + try: - # 设置默认尺寸为3:4比例 - if target_size is None: - target_size = (900, 1200) # 3:4比例 + # 1. 获取base_dir下的所有目录 + all_dirs = [d for d in os.listdir(base_dir) + if os.path.isdir(os.path.join(base_dir, d))] + logging.info(f"找到 {len(all_dirs)} 个图片目录可用于模糊匹配") + + if not all_dirs: + logging.warning(f"基础目录 {base_dir} 下没有可用于匹配的子目录") + return None, 0 + + # 2. 提取对象名称中的关键词 + # 首先通过常见分隔符分割(+、空格、_、-等) + parts = re.split(r'[+\s_\-]', target_name) + keywords = [] + for part in parts: + # 只保留长度大于1的有意义关键词 + if len(part) > 1: + keywords.append(part) + + # 尝试匹配更短的语义单元(例如中文的2-3个字的词语) + for i in range(len(target_name) - 1): + keyword = target_name[i:i+2] # 提取2个字符 + if len(keyword) == 2 and all('\u4e00' <= c <= '\u9fff' for c in keyword): + keywords.append(keyword) + + logging.info(f"用于目录模糊匹配的关键词: {keywords}") + + # 3. 对每个目录进行评分 + dir_scores = {} + for directory in all_dirs: + score = 0 + dir_lower = directory.lower() + # 为每个匹配的关键词增加分数 + for keyword in keywords: + if keyword.lower() in dir_lower: + score += 1 - # 如果没有指定样式,随机选择一种 - if style is None or style not in self.collage_styles: - style = random.choice(self.collage_styles) + # 如果得分大于0(至少匹配一个关键词),记录该目录 + if score > 0: + dir_scores[directory] = score + + # 4. 选择得分最高的目录 + if dir_scores: + best_match = max(dir_scores.items(), key=lambda x: x[1]) + found_dir = best_match[0] + score = best_match[1] + logging.info(f"模糊匹配成功!匹配目录: {found_dir},匹配分数: {score}") + return os.path.join(base_dir, found_dir), score + else: + logging.warning(f"模糊匹配未找到任何包含关键词的目录") + return None, 0 + + except Exception as e: + logging.exception(f"目录模糊匹配过程中出错: {e}") + return None, 0 + + def create_collage_with_style(self, input_dir, style=None, target_size=None): + """ + 创建特定样式的照片拼贴。 + 如果input_dir不存在,会尝试进行模糊匹配。 + + Args: + input_dir: 包含图片的目录路径或目标对象名称 + style: 拼贴画样式,例如"grid_2x2", "overlap"等 + target_size: 拼贴画目标尺寸,例如(900, 1200) + + Returns: + tuple: (PIL.Image 拼贴画对象, 使用的图片文件列表) + """ + try: + # 使用默认样式如果未指定 + if style is None: + if self.collage_style is None: + style = "grid_2x2" + else: + style = self.collage_style + logging.info(f"Using collage style: {style}") + + # 使用默认尺寸如果未指定 + if target_size is None: + target_size = (900, 1200) # 默认尺寸 logging.info(f"Using collage style: {style} with target size: {target_size}") - # 检查目录是否存在 - if not os.path.exists(input_dir): - logging.error(f"Input directory does not exist: {input_dir}") - return None, [] - + # 检查输入目录是否存在 + if not os.path.exists(input_dir) or not os.path.isdir(input_dir): + # 尝试从输入路径获取基础目录和对象名称 + base_dir = os.path.dirname(input_dir) + object_name = os.path.basename(input_dir) + + # 如果基础目录存在,尝试模糊匹配 + if os.path.exists(base_dir) and os.path.isdir(base_dir): + matched_dir, score = self.find_directory_fuzzy_match(base_dir, object_name) + if matched_dir and score > 0: + logging.info(f"使用模糊匹配的图片目录: {matched_dir}") + input_dir = matched_dir + else: + logging.error(f"无法找到匹配的图片目录: {input_dir}") + return None, [] + else: + logging.error(f"输入目录不存在且无法进行模糊匹配: {input_dir}") + return None, [] + # 支持的图片格式 image_extensions = ('.jpg', '.jpeg', '.png', '.bmp') @@ -690,74 +781,82 @@ class ImageCollageCreator: def process_directory(directory_path, style=None, target_size=(900, 1200), output_count=1): """ - 处理指定目录中的图片,创建指定数量的拼贴图。 + 处理目录中的图片并创建指定数量的拼贴图 - 参数: - directory_path: 包含图片的目录路径 - target_size: 拼贴图目标尺寸,默认为 (900, 1200) - output_count: 需要生成的拼贴图数量,默认为 1 - - 返回: - tuple: (拼贴图列表, 使用的图片名称列表的列表),如果生成失败,返回 ([], []) - 拼贴图列表是PIL.Image对象列表 - 图片名称列表是一个列表的列表,每个子列表包含一张拼贴图使用的图片文件名 + 如果给定的目录不存在,会尝试进行模糊匹配。 + + Args: + directory_path: 图片目录路径或目标对象名称 + style: 拼贴画样式,例如"grid_2x2",如果为None则随机选择 + target_size: 拼贴画尺寸,默认为(900, 1200) + output_count: 要生成的拼贴画数量 + + Returns: + list: 成功创建的拼贴图列表 (PIL Image对象) """ logging.info(f"处理目录中的图片并创建 {output_count} 个拼贴图: {directory_path}") - # 创建 ImageCollageCreator 实例 + # 创建拼贴图实例 collage_creator = ImageCollageCreator() - collage_images = [] - used_image_names = [] # 存储每个拼贴图使用的图片文件名 - # 检查目录是否存在 - if not os.path.exists(directory_path): - logging.error(f"目录不存在: {directory_path}") - return [], [] + # 如果指定了样式,设置样式 + if style: + collage_creator.set_collage_style(style) - # 支持的图片格式 - image_extensions = ('.jpg', '.jpeg', '.png', '.bmp') + # 检查目录是否存在 + if not os.path.exists(directory_path) or not os.path.isdir(directory_path): + # 尝试从路径获取基础目录和对象名称 + base_dir = os.path.dirname(directory_path) + object_name = os.path.basename(directory_path) + + # 如果基础目录存在,尝试模糊匹配 + if os.path.exists(base_dir) and os.path.isdir(base_dir): + matched_dir, score = collage_creator.find_directory_fuzzy_match(base_dir, object_name) + if matched_dir and score > 0: + logging.info(f"使用模糊匹配的图片目录: {matched_dir}") + directory_path = matched_dir + else: + logging.error(f"无法找到匹配的图片目录: {directory_path}") + return [] + else: + logging.error(f"输入目录不存在且无法进行模糊匹配: {directory_path}") + return [] - # 获取目录中的所有有效图片文件 + # 获取有效图片文件列表 + image_extensions = ('.jpg', '.jpeg', '.png', '.webp', '.bmp', '.gif') try: all_files = os.listdir(directory_path) - all_images_names = [f for f in all_files - if f.lower().endswith(image_extensions) and os.path.isfile(os.path.join(directory_path, f))] - - if not all_images_names: - logging.error(f"目录中没有有效的图片文件: {directory_path}") - return [], [] - - logging.info(f"目录中找到 {len(all_images_names)} 个有效图片文件") - except Exception as e: - logging.exception(f"列出目录内容时出错: {e}") - return [], [] + image_files = [f for f in all_files + if f.lower().endswith(image_extensions) and os.path.isfile(os.path.join(directory_path, f))] + logging.info(f"目录中找到 {len(image_files)} 个有效图片文件") - # 尝试创建请求数量的拼贴图 + if not image_files: + logging.warning(f"目录中未找到有效图片: {directory_path}") + return [] + except Exception as e: + logging.exception(f"无法读取目录 {directory_path}: {e}") + return [] + + # 创建指定数量的拼贴图 + created_collages = [] for i in range(output_count): - try: - # 创建拼贴图,使用指定样式 - collage, selected_images_names = collage_creator.create_collage_with_style( - directory_path, - style=style, - target_size=target_size - ) + # 如果指定了样式,则使用指定样式;否则让create_collage_with_style自行选择 + if style: + collage, used_images = collage_creator.create_collage_with_style(directory_path, style=style, target_size=target_size) + else: + # 随机选择一种样式 + available_styles = collage_creator.collage_styles + random_style = random.choice(available_styles) + collage, used_images = collage_creator.create_collage_with_style(directory_path, style=random_style, target_size=target_size) - if collage: - collage_images.append(collage) - - # 从输出日志中解析出使用的图片名称 - # 由于我们修改了create_collage_with_style来打印选择的图片 - # 可能需要进一步修改为直接返回选择的图片 - used_image_names.append(selected_images_names) - - logging.info(f"成功创建拼贴图 {i+1}/{output_count}") - else: - logging.error(f"无法创建拼贴图 {i+1}/{output_count}") - except Exception as e: - logging.exception(f"创建拼贴图 {i+1}/{output_count} 时发生异常: {e}") - - logging.info(f"已处理目录 {directory_path},成功创建 {len(collage_images)}/{output_count} 个拼贴图") - return collage_images, used_image_names + if collage: + created_collages.append(collage) + logging.info(f"成功创建拼贴图 {len(created_collages)}/{output_count}") + else: + logging.warning(f"创建拼贴图 {i+1}/{output_count} 失败") + + logging.info(f"已处理目录 {directory_path},成功创建 {len(created_collages)}/{output_count} 个拼贴图") + return created_collages def find_main_subject(image): # ... (keep the existing implementation) ... diff --git a/poster_gen_config.json b/poster_gen_config.json index 345dd3f..718cc5e 100644 --- a/poster_gen_config.json +++ b/poster_gen_config.json @@ -1,7 +1,7 @@ { "date": "4月29日,4月30日, 4月28日, 5月1日", - "num": 10, - "variants": 5, + "num": 15, + "variants": 15, "topic_temperature": 0.2, "topic_top_p": 0.3, "topic_presence_penalty": 1.5, @@ -42,13 +42,13 @@ { "type": "Object", "file_path": [ - "./resource/Object/安吉银润锦江城堡酒店.txt" + "./resource/Object/美的鹭湖鹭栖台酒店.txt" ] }, { "type": "Description", "file_path": [ - "./resource/Object/安吉银润锦江城堡酒店.txt" + "./resource/Object/美的鹭湖鹭栖台酒店.txt" ] }, { diff --git a/utils/__pycache__/__init__.cpython-312.pyc b/utils/__pycache__/__init__.cpython-312.pyc index 22cbbcf..053c766 100644 Binary files a/utils/__pycache__/__init__.cpython-312.pyc and b/utils/__pycache__/__init__.cpython-312.pyc differ diff --git a/utils/__pycache__/content_generator.cpython-312.pyc b/utils/__pycache__/content_generator.cpython-312.pyc index 3803942..49b3b1c 100644 Binary files a/utils/__pycache__/content_generator.cpython-312.pyc and b/utils/__pycache__/content_generator.cpython-312.pyc differ diff --git a/utils/__pycache__/output_handler.cpython-312.pyc b/utils/__pycache__/output_handler.cpython-312.pyc index ee6c618..7da18fc 100644 Binary files a/utils/__pycache__/output_handler.cpython-312.pyc and b/utils/__pycache__/output_handler.cpython-312.pyc differ diff --git a/utils/__pycache__/poster_notes_creator.cpython-312.pyc b/utils/__pycache__/poster_notes_creator.cpython-312.pyc index aedd0de..80700e7 100644 Binary files a/utils/__pycache__/poster_notes_creator.cpython-312.pyc and b/utils/__pycache__/poster_notes_creator.cpython-312.pyc differ diff --git a/utils/__pycache__/prompt_manager.cpython-312.pyc b/utils/__pycache__/prompt_manager.cpython-312.pyc index c86a92e..3cb2e16 100644 Binary files a/utils/__pycache__/prompt_manager.cpython-312.pyc and b/utils/__pycache__/prompt_manager.cpython-312.pyc differ diff --git a/utils/__pycache__/resource_loader.cpython-312.pyc b/utils/__pycache__/resource_loader.cpython-312.pyc index 8431007..32f9cb2 100644 Binary files a/utils/__pycache__/resource_loader.cpython-312.pyc and b/utils/__pycache__/resource_loader.cpython-312.pyc differ diff --git a/utils/__pycache__/tweet_generator.cpython-312.pyc b/utils/__pycache__/tweet_generator.cpython-312.pyc index 977cbbf..03cf21d 100644 Binary files a/utils/__pycache__/tweet_generator.cpython-312.pyc and b/utils/__pycache__/tweet_generator.cpython-312.pyc differ