# 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 ``` ### 请求参数 | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | `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 ``` 祝使用愉快!如有问题请随时反馈。