# 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
```

祝使用愉快！如有问题请随时反馈。

