Merge remote-tracking branch 'origin/xhy_PSD' into wxq_llm

This commit is contained in:
Wang Xiuqiang 2025-05-29 23:21:04 +08:00
commit dfc357f2bb
8 changed files with 371 additions and 1 deletions

View File

@ -21,3 +21,22 @@
```
- 该脚本会自动调用 DeepSeek API 生成 React 组件代码,并将其保存到指定路径。
默认为``output/generated_code.jsx``,可以根据需要修改。
## 图层叠加和PSD导出部分
### 功能组件
- **图层合成**:根据生成的布局配置,将各个图层叠加在一起,生成完整的海报图像。
- **PSD导出**将合成的海报图像保存为标准的PSD格式同时保留各个图层的独立性方便后续编辑。
### 如何调用
1. **环境准备**
```bash
conda create -n ai_service python=3.8
conda activate ai_service
pip install -r requirements.txt
```
2. **运行脚本**
```bash
python export_psd.py #简单生成
python export_psd_from_json.py #从json文件加载布局并生成
python PSD_test.py #在run_pipline.py中的调用方法
```
该脚本会自动调用图层合成模块生成完整海报图像并将其保存为标准PSD格式。

40
configs/example.json Normal file
View File

@ -0,0 +1,40 @@
{
"canvas": {
"width": 1000,
"height": 800,
"mode": "RGB"
},
"layers": [
{
"image_path": "../images/background.jpg",
"name": "background",
"position": {
"left": 0,
"top": 0
},
"visible": true
},
{
"image_path": "../images/nankai.jpg",
"name": "middle",
"position": {
"left": 100,
"top": 100
},
"visible": true
},
{
"image_path": "../images/aaai.png",
"name": "top",
"position": {
"left": 200,
"top": 200
},
"visible": true
}
],
"output": {
"path": "../outputs/configured_output.psd",
"generate_preview": true
}
}

BIN
outputs/.DS_Store vendored Normal file

Binary file not shown.

BIN
outputs/combined_output.psd Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

14
scripts/PSD_test1.py Normal file
View File

@ -0,0 +1,14 @@
from export_psd import create_psd_from_images
if __name__ == "__main__":
image_list = [
'../images/background.jpg',
'../images/nankai.jpg',
'../images/aaai.png',
# Add more images as needed
]
create_psd_from_images(
image_paths=image_list,
output_path='../outputs/combined_output.psd'
)

100
scripts/export_psd.py Normal file
View File

@ -0,0 +1,100 @@
"""
测试文件从多个图片创建PSD文件
将图片列表作为输入从底到顶添加为PSD图层并将图片居中放置
"""
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_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__":
# 示例用法
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'
)

View File

@ -0,0 +1,197 @@
"""
测试文件从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'
)