feat: AI套图分层方案 + Gemini集成 - 4种图案类型处理 + 正片叠底 + 宽高比 + 模型选择
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
340
Server/PLT_API_集成说明.md
Normal file
340
Server/PLT_API_集成说明.md
Normal file
@@ -0,0 +1,340 @@
|
||||
# PLT 裁片处理 API 集成完成
|
||||
|
||||
## ✅ 已完成的工作
|
||||
|
||||
### 1. **核心文件创建**
|
||||
- ✅ `Server/app/api/v1/algorithm.py` - PLT处理API接口
|
||||
- ✅ `Server/pltreader.py` - 已复制到Server目录
|
||||
- ✅ `Server/app/main.py` - 已注册algorithm路由
|
||||
|
||||
### 2. **依赖包更新**
|
||||
- ✅ 添加 `scipy` - 用于匈牙利算法匹配
|
||||
- ✅ 添加 `Pillow` - 用于图像处理和Base64编码
|
||||
- ✅ 已有 `shapely`, `numpy`, `opencv-python-headless`
|
||||
|
||||
### 3. **API功能特性**
|
||||
|
||||
#### 核心功能
|
||||
1. **PLT文件解析** - 自动识别裁片轮廓
|
||||
2. **按尺码分组** - 自动匹配不同尺码的相同裁片
|
||||
3. **生成透明PNG** - 每个裁片独立输出,带Alpha通道
|
||||
4. **精确坐标计算** - 返回厘米单位的中心点和左上角坐标
|
||||
5. **旋转支持** - 可指定0°/90°/-90°/180°旋转
|
||||
6. **双文件匹配** - 可上传两个PLT文件进行轮廓对比
|
||||
|
||||
#### 安全特性
|
||||
- ✅ JWT Token 认证保护
|
||||
- ✅ 需要登录才能访问
|
||||
- ✅ 集成现有用户系统
|
||||
|
||||
---
|
||||
|
||||
## 📋 API 接口说明
|
||||
|
||||
### 接口地址
|
||||
```
|
||||
POST /api/v1/algorithm/process_plt
|
||||
```
|
||||
|
||||
### 请求方式
|
||||
`multipart/form-data`
|
||||
|
||||
### 请求头
|
||||
```
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
### 请求参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||||
|--------|------|------|------|------|
|
||||
| `file` | File | **是** | 标准PLT文件 | `standard.plt` |
|
||||
| `rotated_file` | File | 否 | 旋转后的PLT文件(用于匹配分析) | `rotated.plt` |
|
||||
| `size_labels` | String | **是** | 尺码标签JSON数组 | `["S","M","L","XL","2XL"]` |
|
||||
| `dpi` | Integer | 否 | 输出分辨率(默认150) | `150` |
|
||||
| `rotation` | Integer | 否 | 旋转角度(0/90/-90/180,默认0) | `90` |
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"total_groups": 5,
|
||||
"groups": [
|
||||
{
|
||||
"group_id": 1,
|
||||
"pieces": [
|
||||
{
|
||||
"size": "S",
|
||||
"image_base64": "data:image/png;base64,iVBORw0KGgo...",
|
||||
"width_px": 800,
|
||||
"height_px": 600,
|
||||
"width_cm": 13.54,
|
||||
"height_cm": 10.16,
|
||||
"center_x_cm": 25.4,
|
||||
"center_y_cm": 30.2,
|
||||
"left_cm": 18.63,
|
||||
"top_cm": 35.28
|
||||
},
|
||||
{
|
||||
"size": "M",
|
||||
"image_base64": "data:image/png;base64,iVBORw0KGgo...",
|
||||
"width_px": 820,
|
||||
"height_px": 615,
|
||||
"width_cm": 13.89,
|
||||
"height_cm": 10.41,
|
||||
"center_x_cm": 26.1,
|
||||
"center_y_cm": 30.8,
|
||||
"left_cm": 19.15,
|
||||
"top_cm": 35.60
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"match_analysis": [
|
||||
{
|
||||
"size": "S",
|
||||
"matches": [
|
||||
{
|
||||
"standard_id": 0,
|
||||
"rotated_id": 3,
|
||||
"distance": 0.7032,
|
||||
"angle": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试步骤
|
||||
|
||||
### 1. 安装依赖
|
||||
```bash
|
||||
cd Server
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2. 启动服务
|
||||
```bash
|
||||
cd Server
|
||||
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
### 3. 运行测试脚本
|
||||
```bash
|
||||
cd Server
|
||||
python test_plt_api.py
|
||||
```
|
||||
|
||||
测试脚本会自动:
|
||||
1. 登录获取Token
|
||||
2. 上传PLT文件进行处理
|
||||
3. 显示匹配结果
|
||||
|
||||
---
|
||||
|
||||
## 🔧 技术实现细节
|
||||
|
||||
### 1. **裁片识别算法**
|
||||
- 使用 Shapely 进行几何计算
|
||||
- 自动构建多边形包含关系树
|
||||
- 过滤噪声(面积阈值:0.68%² ~ 80%²)
|
||||
|
||||
### 2. **尺码匹配算法**
|
||||
- **Hausdorff距离** - 衡量轮廓相似度
|
||||
- **匈牙利算法** - 最优匹配分配
|
||||
- 自动处理旋转(0°/90°/180°/270°)
|
||||
- 质心对齐 + 面积归一化
|
||||
|
||||
### 3. **坐标系统**
|
||||
- PLT单位:1016单位 = 1英寸 = 2.54cm
|
||||
- 原点:左下角
|
||||
- Y轴:向上为正(数学坐标系)
|
||||
|
||||
### 4. **图像处理**
|
||||
- OpenCV绘制裁片轮廓
|
||||
- 自动添加Alpha通道(透明背景)
|
||||
- Pillow处理旋转和Base64编码
|
||||
- DPI元数据写入PNG文件
|
||||
|
||||
---
|
||||
|
||||
## 📝 使用示例 (Python)
|
||||
|
||||
```python
|
||||
import requests
|
||||
import json
|
||||
|
||||
# 1. 登录
|
||||
login_response = requests.post(
|
||||
"http://localhost:8000/api/v1/auth/login",
|
||||
json={
|
||||
"username": "admin",
|
||||
"password": "123456",
|
||||
"device_id": "test-device"
|
||||
}
|
||||
)
|
||||
token = login_response.json()["access_token"]
|
||||
|
||||
# 2. 处理PLT文件
|
||||
with open("standard.plt", "rb") as f1:
|
||||
files = [
|
||||
("file", ("standard.plt", f1, "application/octet-stream"))
|
||||
]
|
||||
data = {
|
||||
"size_labels": json.dumps(["S", "M", "L", "XL", "2XL"]),
|
||||
"dpi": 150,
|
||||
"rotation": 90 # 顺时针旋转90度
|
||||
}
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
response = requests.post(
|
||||
"http://localhost:8000/api/v1/algorithm/process_plt",
|
||||
files=files,
|
||||
data=data,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
result = response.json()
|
||||
print(f"共生成 {result['total_groups']} 组裁片")
|
||||
|
||||
# 3. 保存图片
|
||||
for group in result["groups"]:
|
||||
for piece in group["pieces"]:
|
||||
# 提取Base64数据
|
||||
base64_data = piece["image_base64"].split(",")[1]
|
||||
|
||||
# 解码并保存
|
||||
import base64
|
||||
img_data = base64.b64decode(base64_data)
|
||||
with open(f"{piece['size']}-{group['group_id']}.png", "wb") as img_file:
|
||||
img_file.write(img_data)
|
||||
|
||||
print(f"已保存: {piece['size']}-{group['group_id']}.png")
|
||||
print(f" 位置: ({piece['left_cm']}, {piece['top_cm']}) cm")
|
||||
print(f" 尺寸: {piece['width_cm']} x {piece['height_cm']} cm")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Photoshop插件集成要点
|
||||
|
||||
### 1. **创建画布**
|
||||
```javascript
|
||||
// 根据API返回的尺寸创建画布
|
||||
var canvasWidth = 100; // cm,根据实际需求
|
||||
var canvasHeight = 150; // cm
|
||||
var dpi = 150;
|
||||
|
||||
var doc = app.documents.add(
|
||||
UnitValue(canvasWidth, "cm"),
|
||||
UnitValue(canvasHeight, "cm"),
|
||||
dpi,
|
||||
"PLT裁片",
|
||||
NewDocumentMode.RGB,
|
||||
DocumentFill.TRANSPARENT
|
||||
);
|
||||
```
|
||||
|
||||
### 2. **加载Base64图片**
|
||||
```javascript
|
||||
function loadBase64Image(base64String, layerName) {
|
||||
// 去除前缀
|
||||
var base64Data = base64String.split(",")[1];
|
||||
|
||||
// 保存为临时文件
|
||||
var tempFile = new File(Folder.temp + "/temp_piece.png");
|
||||
tempFile.encoding = "BINARY";
|
||||
tempFile.open("w");
|
||||
tempFile.write(decode64(base64Data));
|
||||
tempFile.close();
|
||||
|
||||
// 打开并复制到主文档
|
||||
var tempDoc = app.open(tempFile);
|
||||
tempDoc.activeLayer.copy();
|
||||
app.activeDocument = mainDoc;
|
||||
var newLayer = mainDoc.paste();
|
||||
newLayer.name = layerName;
|
||||
tempDoc.close(SaveOptions.DONOTSAVECHANGES);
|
||||
tempFile.remove();
|
||||
|
||||
return newLayer;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **定位图层**
|
||||
```javascript
|
||||
function positionLayer(layer, leftCm, topCm, dpi) {
|
||||
// 厘米转像素
|
||||
var leftPx = leftCm * dpi / 2.54;
|
||||
var topPx = topCm * dpi / 2.54;
|
||||
|
||||
// 移动到指定位置
|
||||
var deltaX = leftPx - layer.bounds[0];
|
||||
var deltaY = topPx - layer.bounds[1];
|
||||
layer.translate(deltaX, deltaY);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **文件编码** - PLT文件必须是文本格式,如果是二进制格式会导致解析失败
|
||||
2. **尺码数量** - `size_labels` 的数量必须与PLT文件中的实际尺码数量一致
|
||||
3. **内存占用** - 处理大型PLT文件(>1000个裁片)可能需要较长时间
|
||||
4. **坐标系** - Photoshop的Y轴向下,如需适配可能需要翻转Y坐标
|
||||
|
||||
---
|
||||
|
||||
## 🐛 故障排查
|
||||
|
||||
### 问题1: 导入错误 `cannot import name 'algorithm'`
|
||||
**解决**:
|
||||
```bash
|
||||
# 确保已重启uvicorn服务
|
||||
python -m uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
### 问题2: `ModuleNotFoundError: No module named 'scipy'`
|
||||
**解决**:
|
||||
```bash
|
||||
pip install scipy Pillow
|
||||
```
|
||||
|
||||
### 问题3: PLT文件解析失败
|
||||
**检查**:
|
||||
- 文件是否是文本格式(用记事本能打开)
|
||||
- 文件编码是否正确(建议UTF-8或GBK)
|
||||
- 文件是否包含有效的PLT命令(IN, PU, PD, PA等)
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- `Server/docs/API_PLT_Processing.md` - 详细API文档
|
||||
- `Server/test_plt_api.py` - 测试示例代码
|
||||
- `pltreader.py` - PLT解析器源码
|
||||
- `run.py` - 命令行工具示例
|
||||
|
||||
---
|
||||
|
||||
## 🎉 完成!
|
||||
|
||||
现在你可以启动服务器并测试API了:
|
||||
|
||||
```bash
|
||||
cd D:\main\DesignerCEP\Server
|
||||
python -m uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
然后在浏览器访问文档:
|
||||
```
|
||||
http://localhost:8000/docs
|
||||
```
|
||||
|
||||
祝使用愉快!如有问题请随时反馈。
|
||||
|
||||
Reference in New Issue
Block a user