修复了一个选图过程的bug

This commit is contained in:
jinye_huang 2025-05-09 15:40:41 +08:00
parent 4fa2165abd
commit 5fa4f0d2d4

View File

@ -11,6 +11,7 @@ from PIL import ImageEnhance, ImageFilter
from .output_handler import OutputHandler
import io
import math
from core.simple_collage import process_directory as process_collage
# 尝试导入 scipy如果失败则标记
try:
@ -193,10 +194,10 @@ class PosterNotesCreator:
output_filename_template: 输出文件名模板
variation_strength: 变化强度可以是 'low', 'medium', 'high'
extra_effects: 是否应用额外效果
collage_style: 拼图风格可以是 'grid', 'mosaic', 'polaroid', 'slice', 'random' None不使用拼图
collage_style: 拼图风格可以是 'grid', 'mosaic', 'polaroid', 'slice', 'random'
Returns:
List[str]: 保存的笔记图像路径列表
List[str]: 保存的图像路径列表
"""
logger.info(f"开始为主题 {topic_index} 变体 {variant_index} 选择额外配图")
@ -333,56 +334,80 @@ class PosterNotesCreator:
seed,
variation_strength,
extra_effects,
collage_style=None
collage_style="slice"
):
"""处理单张图像 - 此方法可在独立进程中运行"""
try:
# 加载图像
image = Image.open(image_path)
# 使用core.simple_collage模块处理图像
style = collage_style if collage_style else "slice"
# 处理图像,优先使用拼图处理而不是数字指纹模块
if collage_style:
# 如果指定了拼图风格,则使用拼图处理
processed_image = self.create_collage_image(
image,
(3, 4),
style=collage_style,
seed=seed
# 创建临时目录来存放图像以便传递给process_collage函数
import tempfile
import shutil
with tempfile.TemporaryDirectory() as temp_dir:
# 复制图像到临时目录
temp_image_path = os.path.join(temp_dir, image_filename)
shutil.copy2(image_path, temp_image_path)
# 设置随机种子以确保结果一致性
if seed is not None:
random.seed(seed)
np.random.seed(seed)
# 调用core.simple_collage模块处理图像
target_size = (900, 1200) # 3:4比例
collage_images, used_image_filenames = process_collage(
temp_dir,
style=style,
target_size=target_size,
output_count=1
)
else:
# 调整为目标比例但不使用数字指纹模块
processed_image = self.optimized_process_image(
image,
(3, 4),
add_variation=True,
seed=seed,
variation_strength=variation_strength,
extra_effects=False # 不使用高强度数字指纹模块
# 重置随机种子
if seed is not None:
random.seed()
np.random.seed()
if not collage_images or len(collage_images) == 0:
logger.error(f"拼图模块没有生成有效的图像: {image_filename}")
return None
processed_image = collage_images[0]
# 确保图像是RGB模式解决"cannot write mode RGBA as JPEG"错误
if processed_image.mode == 'RGBA':
logger.debug(f"将RGBA图像转换为RGB模式: {image_filename}")
# 创建白色背景并粘贴RGBA图像
background = Image.new('RGB', processed_image.size, (255, 255, 255))
background.paste(processed_image, mask=processed_image.split()[3]) # 使用alpha通道作为mask
processed_image = background
elif processed_image.mode != 'RGB':
logger.debug(f"{processed_image.mode}图像转换为RGB模式: {image_filename}")
processed_image = processed_image.convert('RGB')
# 创建元数据
additional_metadata = {
"original_image": image_filename,
"additional_index": index + 1,
"source_dir": source_dir,
"is_additional_image": True,
"processed": True,
"aspect_ratio": "3:4",
"collage_style": style
}
# 使用输出处理器保存图像
return self.output_handler.handle_generated_image(
run_id,
topic_index,
variant_index,
'additional', # 图像类型为additional
processed_image,
output_filename,
additional_metadata
)
# 创建元数据
additional_metadata = {
"original_image": image_filename,
"additional_index": index + 1,
"source_dir": source_dir,
"is_additional_image": True,
"processed": True,
"aspect_ratio": "3:4",
"variation_applied": True,
"variation_strength": variation_strength,
"collage_style": collage_style if collage_style else "none"
}
# 使用输出处理器保存图像
return self.output_handler.handle_generated_image(
run_id,
topic_index,
variant_index,
'additional', # 图像类型为additional
processed_image,
output_filename,
additional_metadata
)
except Exception as e:
logger.error(f"处理图像时出错 '{image_filename}': {e}")
logger.error(traceback.format_exc())
@ -609,63 +634,30 @@ class PosterNotesCreator:
elif style == "slice":
# 切片风格: 水平或垂直切片并错开
direction = random.choice(["horizontal", "vertical"])
# 固定使用水平切片
collage = Image.new('RGB', (base_width, base_height), (255, 255, 255))
if direction == "horizontal":
# 水平切片
num_slices = random.randint(4, 8)
slice_height = base_height // num_slices
# 水平切片
num_slices = 6 # 固定切片数量
slice_height = base_height // num_slices
for i in range(num_slices):
# 切出原图片片
top = i * slice_height
bottom = min(top + slice_height, base_height)
slice_img = image_base.crop((0, top, base_width, bottom))
for i in range(num_slices):
# 切出原图片片
top = i * slice_height
bottom = min(top + slice_height, base_height)
slice_img = image_base.crop((0, top, base_width, bottom))
# 确定偏移量
offset = random.randint(-30, 30) if i % 2 == 1 else 0
# 确保偏移后不超出边界
offset = max(-base_width // 4, min(base_width // 4, offset))
# 粘贴到拼图,带偏移
paste_left = offset
if paste_left < 0:
# 如果左侧偏移超出边界,需要裁剪
slice_img = slice_img.crop((-paste_left, 0, slice_img.width, slice_img.height))
paste_left = 0
elif paste_left + slice_img.width > base_width:
# 如果右侧偏移超出边界,需要裁剪
# 只在奇数行应用固定偏移,让效果更整齐
offset = 20 if i % 2 == 1 else 0 # 固定偏移量,更可控
# 粘贴到拼图,带偏移
paste_left = offset
if paste_left > 0:
# 如果右侧偏移超出边界,需要裁剪
if paste_left + slice_img.width > base_width:
slice_img = slice_img.crop((0, 0, base_width - paste_left, slice_img.height))
collage.paste(slice_img, (paste_left, top))
else:
# 垂直切片
num_slices = random.randint(4, 8)
slice_width = base_width // num_slices
for i in range(num_slices):
# 切出原图片片
left = i * slice_width
right = min(left + slice_width, base_width)
slice_img = image_base.crop((left, 0, right, base_height))
# 确定偏移量
offset = random.randint(-30, 30) if i % 2 == 1 else 0
# 确保偏移后不超出边界
offset = max(-base_height // 4, min(base_height // 4, offset))
# 粘贴到拼图,带偏移
paste_top = offset
if paste_top < 0:
# 如果上侧偏移超出边界,需要裁剪
slice_img = slice_img.crop((0, -paste_top, slice_img.width, slice_img.height))
paste_top = 0
elif paste_top + slice_img.height > base_height:
# 如果下侧偏移超出边界,需要裁剪
slice_img = slice_img.crop((0, 0, slice_img.width, base_height - paste_top))
collage.paste(slice_img, (left, paste_top))
collage.paste(slice_img, (paste_left, top))
else:
# 默认情况,直接返回调整后的图像
@ -682,7 +674,7 @@ class PosterNotesCreator:
logger.info(f"拼图图像创建完成,风格: {style}")
return result
def add_dct_noise(self, image: Image.Image, intensity: float = 0.1, block_size: int = 8) -> Image.Image:
"""
在DCT域添加噪声以对抗pHash (需要Scipy) - 强化版
@ -1799,10 +1791,10 @@ def select_additional_images(
output_filename_template: 输出文件名模板
variation_strength: 变化强度
extra_effects: 是否应用额外效果
collage_style: 拼图风格可以是 'grid', 'mosaic', 'polaroid', 'slice', 'random' None不使用拼图
collage_style: 拼图风格可以是 'grid', 'mosaic', 'polaroid', 'slice', 'random'
Returns:
List[str]: 保存的笔记图像路径列表
List[str]: 保存的图像路径列表
"""
logger.info(f"开始为主题 {topic_index} 变体 {variant_index} 选择额外配图")
@ -1814,7 +1806,7 @@ def select_additional_images(
# 创建处理器实例
creator = PosterNotesCreator(output_handler)
# 使用修改后的方法处理图像
# 使用拼图处理图像
return creator.create_additional_images(
run_id,
topic_index,
@ -1826,4 +1818,4 @@ def select_additional_images(
variation_strength,
extra_effects,
collage_style
)
)