ai_service/scripts/export_psd_from_json.py
2025-05-22 10:50:10 +08:00

197 lines
7.0 KiB
Python
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.

"""
测试文件从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'
)