Merge remote-tracking branch 'origin/xhy_PSD' into wxq_llm
This commit is contained in:
commit
dfc357f2bb
19
README.md
19
README.md
@ -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
40
configs/example.json
Normal 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
BIN
outputs/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
outputs/combined_output.psd
Normal file
BIN
outputs/combined_output.psd
Normal file
Binary file not shown.
BIN
outputs/combined_output_预览.png
Normal file
BIN
outputs/combined_output_预览.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
14
scripts/PSD_test1.py
Normal file
14
scripts/PSD_test1.py
Normal 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
100
scripts/export_psd.py
Normal 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'
|
||||
)
|
197
scripts/export_psd_from_json.py
Normal file
197
scripts/export_psd_from_json.py
Normal 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'
|
||||
)
|
Loading…
Reference in New Issue
Block a user