基本一致的psd格式

This commit is contained in:
jinye_huang 2025-07-27 17:17:42 +08:00
parent 4d157453ce
commit 9da9324484
2 changed files with 106 additions and 45 deletions

View File

@ -542,58 +542,45 @@ class VibrantTemplate(BaseTemplate):
logger.error("无法加载图片")
return None
# 参考原始合成模式的PSD版本实现
main_image = self.image_processor.resize_image(image=main_image, target_size=self.size)
estimated_height = self._estimate_content_height(content)
gradient_start = self._detect_gradient_start_position(main_image, estimated_height)
# 创建新的PSD文档使用透明背景
psd = PSDImage.new("RGBA", self.size, color=(0, 0, 0, 0))
logger.info(f"创建PSD文档尺寸: {self.size}")
# 1. 添加背景图层
background_layer = PixelLayer.frompil(main_image, psd, "Background")
psd.append(background_layer)
logger.info("✓ 添加背景图层")
# 2. 添加毛玻璃效果层
glass_overlay = self._create_glass_overlay_layer(main_image, gradient_start, theme_color)
if glass_overlay:
glass_layer = PixelLayer.frompil(glass_overlay, psd, "Glass Effect")
psd.append(glass_layer)
logger.info("✓ 添加毛玻璃效果层")
# 3-7. 添加文字图层
text_layers = self._create_text_layers(content, gradient_start)
for layer_name, layer_image in text_layers.items():
if layer_image:
text_layer = PixelLayer.frompil(layer_image, psd, layer_name)
psd.append(text_layer)
logger.info(f"✓ Added {layer_name} layer")
# 应用与常规模式相同的尺寸调整 (1350x1800)
# === 第一步创建与常规模式完全相同的最终结果作为Reference ===
canvas = self._create_composite_image(main_image, gradient_start, theme_color)
canvas = self._render_texts(canvas, content, gradient_start)
final_canvas = canvas.resize((1350, 1800), Image.LANCZOS)
# === 第二步为PSD创建可编辑的图层版本 ===
final_size = (1350, 1800)
psd = PSDImage.new("RGBA", final_size, color=(0, 0, 0, 0))
logger.info(f"创建PSD文档尺寸: {final_size}")
# 图层1完美一致的参考图层
composite_layer = PixelLayer.frompil(final_canvas, psd, "Perfect Reference")
psd.append(composite_layer)
logger.info("✓ 添加完美参考图层")
# 调整PSD文档尺寸以匹配常规输出
if psd.size != final_size:
logger.info(f"调整PSD尺寸: {psd.size} -> {final_size}")
# 重新创建PSD文档以匹配最终尺寸
final_psd = PSDImage.new("RGBA", final_size, color=(0, 0, 0, 0))
# 调整并添加所有图层
for layer in psd:
try:
if hasattr(layer, 'composite'):
layer_image = layer.composite()
if layer_image:
# 调整图层尺寸
resized_layer = layer_image.resize(final_size, Image.LANCZOS)
final_layer = PixelLayer.frompil(resized_layer, final_psd, layer.name)
final_psd.append(final_layer)
except Exception as e:
logger.warning(f"调整图层 {layer.name} 失败: {e}")
psd = final_psd
# === 第三步:按合成模式创建可编辑图层 ===
# 图层2背景+毛玻璃的复合底层模拟canvas状态
base_composite = self._create_composite_image(main_image, gradient_start, theme_color)
base_composite_scaled = base_composite.resize(final_size, Image.LANCZOS)
base_layer = PixelLayer.frompil(base_composite_scaled, psd, "Background + Glass")
psd.append(base_layer)
logger.info("✓ 添加背景+毛玻璃复合图层")
# 图层3纯文字图层在透明背景上模拟_render_texts的结果
text_only_canvas = self._create_text_only_layer(content, gradient_start, self.size)
if text_only_canvas:
text_only_scaled = text_only_canvas.resize(final_size, Image.LANCZOS)
text_layer = PixelLayer.frompil(text_only_scaled, psd, "All Text Content")
psd.append(text_layer)
logger.info("✓ 添加纯文字图层")
logger.info(f"PSD包含{len(list(psd))}个图层,遵循原始合成逻辑")
# 保存PSD文件
psd.save(output_path)
logger.info(f"✓ PSD文件已保存: {output_path} (尺寸: {psd.size})")
@ -615,6 +602,8 @@ class VibrantTemplate(BaseTemplate):
logger.error(f"创建毛玻璃层失败: {e}")
return None
def _create_text_layers(self, content: Dict[str, Any], gradient_start: int) -> Dict[str, Optional[Image.Image]]:
"""创建各个文字图层"""
layers = {}
@ -659,6 +648,78 @@ class VibrantTemplate(BaseTemplate):
return layers
def _create_text_only_layer(self, content: Dict[str, Any], gradient_start: int, canvas_size: tuple) -> Optional[Image.Image]:
"""创建纯文字图层透明背景模拟_render_texts的渲染逻辑"""
try:
# 创建透明画布
text_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
draw = ImageDraw.Draw(text_canvas)
width, height = canvas_size
center_x = width // 2
# 使用与原始方法相同的布局计算
left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
# 页脚
footer_y = height - 30
self._render_footer(draw, content, footer_y, left_margin, right_margin)
# 标题和副标题
title_y = gradient_start + 40
current_y = self._render_title_subtitle(draw, content, title_y, center_x, left_margin, right_margin)
# 左右栏内容
content_area_width = right_margin - left_margin
left_column_width = int(content_area_width * 0.5)
right_column_x = left_margin + left_column_width
content_start_y = current_y + 30
self._render_left_column(draw, content, content_start_y, left_margin, left_column_width, height)
self._render_right_column(draw, content, content_start_y, right_column_x, right_margin)
return text_canvas
except Exception as e:
logger.error(f"创建纯文字图层失败: {e}")
return None
def _create_text_only_layer(self, content: Dict[str, Any], gradient_start: int, canvas_size: tuple) -> Optional[Image.Image]:
"""创建纯文字图层透明背景模拟_render_texts的渲染逻辑"""
try:
# 创建透明画布
text_canvas = Image.new('RGBA', canvas_size, (0, 0, 0, 0))
draw = ImageDraw.Draw(text_canvas)
width, height = canvas_size
center_x = width // 2
# 使用与原始方法相同的布局计算
left_margin, right_margin = self._calculate_content_margins(content, width, center_x)
# 页脚
footer_y = height - 30
self._render_footer(draw, content, footer_y, left_margin, right_margin)
# 标题和副标题
title_y = gradient_start + 40
current_y = self._render_title_subtitle(draw, content, title_y, center_x, left_margin, right_margin)
# 左右栏内容
content_area_width = right_margin - left_margin
left_column_width = int(content_area_width * 0.5)
right_column_x = left_margin + left_column_width
content_start_y = current_y + 30
self._render_left_column(draw, content, content_start_y, left_margin, left_column_width, height)
self._render_right_column(draw, content, content_start_y, right_column_x, right_margin)
return text_canvas
except Exception as e:
logger.error(f"创建纯文字图层失败: {e}")
return None
def _draw_text_with_outline_simple(self, draw: ImageDraw.Draw, position: Tuple[int, int],
text: str, font: ImageFont.FreeTypeFont,
text_color: Tuple[int, int, int, int] = (255, 255, 255, 255),