""" 测试文件:从JSON配置文件创建PSD文件 支持通过配置文件精确控制图层位置和属性 """ import json from psd_tools import PSDImage from PIL import Image from psd_tools.constants import Compression import os from typing import List, Tuple # 导入PixelLayer类,用于从PIL图像创建图层 from psd_tools.api.layers import PixelLayer def create_psd_from_config(config_file: str) -> None: """ 从JSON配置文件创建PSD文件 参数: config_file: JSON配置文件路径 """ # 确保配置文件存在 if not os.path.exists(config_file): raise FileNotFoundError(f"配置文件不存在: {config_file}") # 读取JSON配置文件 with open(config_file, 'r', encoding='utf-8') as f: config = json.load(f) try: # 1. 从配置创建PSD文件 canvas = config['canvas'] psd = PSDImage.new( canvas['mode'], (canvas['width'], canvas['height']) ) # 2. 根据配置添加图层 for layer_config in config['layers']: # 打开图片 image = Image.open(layer_config['image_path']) # 获取位置信息 position = layer_config['position'] left = position['left'] top = position['top'] # 创建图层 layer = PixelLayer.frompil( image, psd, layer_config['name'], top, left, Compression.RLE ) # 设置图层可见性 layer.visible = layer_config.get('visible', True) psd.append(layer) # 3. 确保所有图层都是可见的 for layer in psd: if not layer.visible: print(f"图层 {layer.name} 不可见,正在设置为可见") layer.visible = True # 4. 生成合成图像并更新PSD文件的图像数据 composite_image = psd.composite(force=True) psd._record.image_data.set_data( [channel.tobytes() for channel in composite_image.split()], psd._record.header ) # 5. 保存PSD文件 output_config = config['output'] output_path = output_config['path'] # 确保输出目录存在 os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True) psd.save(output_path) print(f"PSD文件已成功创建,保存在: {output_path}") # 6. 生成预览(如果配置中启用) if output_config.get('generate_preview', False): preview_path = os.path.splitext(output_path)[0] + "_预览.png" composite_image.save(preview_path) print(f"预览已保存在: {preview_path}") # 7. 验证PSD文件结构 saved_psd = PSDImage.open(output_path) print(f"PSD文件信息: {saved_psd}") print(f"图层数量: {len(saved_psd)}") for i, layer in enumerate(saved_psd): print(f"图层 {i}: {layer.name}, 位置: ({layer.left}, {layer.top}), 大小: {layer.width}x{layer.height}") except Exception as e: print(f"创建PSD文件时出错: {e}") def create_psd_from_images( image_paths: List[str], output_path: str, canvas_size: Tuple[int, int] = (1000, 800), mode: str = 'RGB' ) -> None: """ 从图片列表创建PSD文件,将图片从底到顶堆叠(保留原有功能) 参数: image_paths: 图片路径列表 output_path: 保存PSD文件的路径 canvas_size: PSD画布大小,格式为(宽度, 高度) mode: PSD文件的颜色模式 """ # 确保输出目录存在 os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True) try: # 1. 创建一个新的PSD文件 psd = PSDImage.new(mode, canvas_size) # 2. 打开并添加每个图片作为图层 for i, img_path in enumerate(image_paths): # 打开图片 image = Image.open(img_path) # 计算居中位置 left = (canvas_size[0] - image.width) // 2 top = (canvas_size[1] - image.height) // 2 # 根据图片文件名创建图层名称 layer_name = f"layer {i+1} - {os.path.basename(img_path)}" # 创建并添加图层 layer = PixelLayer.frompil(image, psd, layer_name, top, left, Compression.RLE) # 确保图层可见 layer.visible = True psd.append(layer) # 确保所有图层都是可见的 for layer in psd: if not layer.visible: print(f"图层 {layer.name} 不可见,正在设置为可见") layer.visible = True # 生成合成图像 composite_image = psd.composite(force=True) # 更新PSD文件的图像数据 psd._record.image_data.set_data([channel.tobytes() for channel in composite_image.split()], psd._record.header) # 3. 保存PSD文件 psd.save(output_path) print(f"PSD文件已成功创建,保存在: {output_path}") # 4. 生成并保存预览 preview_path = os.path.splitext(output_path)[0] + "_预览.png" composite_image.save(preview_path) print(f"预览已保存在: {preview_path}") # 5. 验证PSD文件结构 saved_psd = PSDImage.open(output_path) print(f"PSD文件信息: {saved_psd}") print(f"图层数量: {len(saved_psd)}") for i, layer in enumerate(saved_psd): print(f"图层 {i}: {layer.name}, 位置: ({layer.left}, {layer.top}), 大小: {layer.width}x{layer.height}") except Exception as e: print(f"创建PSD文件时出错: {e}") if __name__ == "__main__": # 方法1: 使用JSON配置文件 print("=== 使用JSON配置文件创建PSD ===") create_psd_from_config('../configs/example.json') print("\n" + "="*50 + "\n") # 方法2: 使用原有的图片列表方法(保留兼容性) print("=== 使用图片列表创建PSD(居中布局)===") image_list = [ '../images/background.jpg', # 底层图片 '../images/nankai.jpg', # 中间图片 '../images/aaai.png', # 顶层图片 # 可以根据需要添加更多图片 ] create_psd_from_images( image_paths=image_list, output_path='../outputs/combined_output.psd' )