307 lines
7.2 KiB
Markdown
307 lines
7.2 KiB
Markdown
# 后端Fabric.js JSON格式规范
|
||
|
||
## 标准格式要求
|
||
|
||
### 1. 根对象结构
|
||
```json
|
||
{
|
||
"version": "5.3.0",
|
||
"width": 1350,
|
||
"height": 1800,
|
||
"objects": [
|
||
// 对象数组
|
||
]
|
||
}
|
||
```
|
||
|
||
### 2. 对象类型要求(只使用标准Fabric.js类型)
|
||
|
||
#### ✅ 允许的标准类型:
|
||
- `rect` - 矩形
|
||
- `circle` - 圆形
|
||
- `textbox` - 文本框
|
||
- `text` - 文本
|
||
- `image` - 图片
|
||
- `line` - 线条
|
||
- `polygon` - 多边形
|
||
- `path` - 路径
|
||
- `group` - 组
|
||
|
||
#### ❌ 禁止的自定义类型:
|
||
- `CustomRect` -> 应改为 `rect`
|
||
- `CustomTextbox` -> 应改为 `textbox`
|
||
- `CustomCircle` -> 应改为 `circle`
|
||
- `CustomGroup` -> 应改为 `group`
|
||
- `ThinTailArrow` -> 应改为 `path` 或 `rect`
|
||
- `Arrow` -> 应改为 `path` 或 `rect`
|
||
|
||
### 3. 基本对象属性要求
|
||
|
||
#### 所有对象必须包含:
|
||
```json
|
||
{
|
||
"type": "rect", // 标准类型
|
||
"left": 100, // 数值,非null
|
||
"top": 50, // 数值,非null
|
||
"width": 200, // 数值 > 0
|
||
"height": 100, // 数值 > 0
|
||
"fill": "#ffffff",
|
||
"opacity": 1,
|
||
"angle": 0,
|
||
"scaleX": 1,
|
||
"scaleY": 1
|
||
}
|
||
```
|
||
|
||
#### 文本对象额外属性:
|
||
```json
|
||
{
|
||
"type": "textbox",
|
||
"text": "实际文本内容", // 非空字符串
|
||
"fontSize": 16, // 数值 > 0
|
||
"fontFamily": "Arial", // 有效字体名
|
||
"fill": "#000000"
|
||
}
|
||
```
|
||
|
||
#### 图片对象要求:
|
||
```json
|
||
{
|
||
"type": "image",
|
||
"src": "https://example.com/image.jpg", // 必须是完整有效的URL
|
||
"width": 300, // 实际图片宽度
|
||
"height": 200 // 实际图片高度
|
||
}
|
||
```
|
||
|
||
**重要:图片src必须是可访问的完整URL,不能是:**
|
||
- 相对路径如 `preview1.jpg`
|
||
- 本地路径如 `./images/test.png`
|
||
- 占位符如 `image1.jpg`
|
||
|
||
### 4. 组对象格式:
|
||
```json
|
||
{
|
||
"type": "group",
|
||
"objects": [
|
||
// 组内的标准对象
|
||
]
|
||
}
|
||
```
|
||
|
||
### 5. 完整示例:
|
||
```json
|
||
{
|
||
"version": "5.3.0",
|
||
"width": 1350,
|
||
"height": 1800,
|
||
"objects": [
|
||
{
|
||
"type": "rect",
|
||
"left": 100,
|
||
"top": 100,
|
||
"width": 200,
|
||
"height": 150,
|
||
"fill": "#ff0000",
|
||
"opacity": 1,
|
||
"angle": 0,
|
||
"scaleX": 1,
|
||
"scaleY": 1
|
||
},
|
||
{
|
||
"type": "textbox",
|
||
"left": 50,
|
||
"top": 300,
|
||
"width": 300,
|
||
"height": 50,
|
||
"text": "这是文本内容",
|
||
"fontSize": 24,
|
||
"fontFamily": "Arial",
|
||
"fill": "#000000",
|
||
"opacity": 1
|
||
},
|
||
{
|
||
"type": "image",
|
||
"left": 400,
|
||
"top": 100,
|
||
"width": 200,
|
||
"height": 200,
|
||
"src": "https://example.com/path/to/image.jpg",
|
||
"opacity": 1
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
## 复杂装饰元素处理策略
|
||
|
||
### 问题:复杂的装饰性元素(如按钮、装饰图案)
|
||
- **旧方案**:使用多个形状组合(rect + circle + path等)
|
||
- **新方案**:将复杂元素预渲染为图像
|
||
|
||
### 实现方式:
|
||
1. **后端预渲染**:将复杂的按钮样式、装饰图案等渲染为PNG图像
|
||
2. **托管图像**:将这些装饰图像托管在可访问的URL上
|
||
3. **JSON引用**:在fabric.js JSON中使用标准`image`对象引用
|
||
|
||
### 示例:按钮元素
|
||
```json
|
||
// ❌ 旧方式:复杂形状组合
|
||
{
|
||
"type": "group",
|
||
"objects": [
|
||
{"type": "rect", "fill": "linear-gradient(...)", ...},
|
||
{"type": "circle", "fill": "rgba(...)", ...},
|
||
{"type": "path", "path": "M10,10 L20,20...", ...}
|
||
]
|
||
}
|
||
|
||
// ✅ 新方式:预渲染图像
|
||
{
|
||
"type": "image",
|
||
"left": 100,
|
||
"top": 200,
|
||
"width": 120,
|
||
"height": 40,
|
||
"src": "https://your-domain.com/api/decorative/button_style_1.png",
|
||
"opacity": 1
|
||
}
|
||
```
|
||
|
||
## 关键要求总结:
|
||
|
||
1. **只使用Fabric.js标准对象类型**
|
||
2. **所有数值属性必须有效(非null、非0宽高)**
|
||
3. **图片src必须是完整可访问的URL**
|
||
4. **包含完整的width/height信息**
|
||
5. **遵循标准JSON结构**
|
||
6. **复杂装饰元素使用预渲染图像**
|
||
|
||
这样前端就可以直接使用 `canvas.loadFromJSON()` 而无需任何预处理!
|
||
|
||
## 装饰性图像处理流程
|
||
|
||
### 完整的端到端流程:
|
||
|
||
1. **Python端生成装饰图像**
|
||
- 使用PIL动态生成按钮、标签、价格背景等装饰元素
|
||
- 返回base64编码的PNG图像数据
|
||
- 在fabric.js JSON中使用占位符URL(https://placeholder.qiniu.com/decorative/)
|
||
|
||
2. **Java端处理装饰图像**
|
||
- 接收装饰图像的base64数据
|
||
- 上传每个装饰图像到七牛云存储
|
||
- 获取七牛云的真实URL
|
||
- 替换fabric.js JSON中的占位符URL为真实URL
|
||
|
||
3. **前端使用**
|
||
- 接收更新后的fabric.js JSON(包含真实的图像URL)
|
||
- 直接使用`canvas.loadFromJSON()`加载完整设计
|
||
|
||
### API响应结构:
|
||
```json
|
||
{
|
||
"requestId": "poster-20250101-120000-abc123",
|
||
"templateId": "vibrant",
|
||
"resultImagesBase64": [...],
|
||
"fabricJsons": [
|
||
{
|
||
"id": "fabric_json_0",
|
||
"data": "base64_encoded_json...",
|
||
"jsonData": {
|
||
"version": "5.3.0",
|
||
"width": 1350,
|
||
"height": 1800,
|
||
"objects": [
|
||
{
|
||
"type": "image",
|
||
"src": "https://qiniu-domain.com/poster/decorative/2025/01/01/button_1234567890.png",
|
||
"left": 100,
|
||
"top": 200,
|
||
"width": 200,
|
||
"height": 60
|
||
}
|
||
]
|
||
}
|
||
}
|
||
],
|
||
"decorativeImages": {
|
||
"button": {
|
||
"originalId": "button",
|
||
"type": "button",
|
||
"qiniuUrl": "https://qiniu-domain.com/poster/decorative/2025/01/01/button_1234567890.png",
|
||
"uploadSuccess": true
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 实现状态
|
||
|
||
### ✅ 已完成:
|
||
- 标准fabric.js JSON格式输出
|
||
- 简化的文本布局(只使用textbox/text)
|
||
- 装饰性图像生成器(按钮、标签、价格背景)
|
||
- 装饰图像上传到七牛云的完整流程
|
||
- fabric.js JSON中占位符URL自动替换
|
||
- 统一1350x1800基础尺寸
|
||
- 端到端的装饰图像处理工作流
|
||
|
||
## 统一生成架构(重大改进)
|
||
|
||
### 问题解决:
|
||
**原问题**:fabric.js JSON和PNG分开生成,导致参数不一致、位置偏差等问题。
|
||
|
||
**解决方案**:VibrantTemplate统一生成模式
|
||
- PNG和Fabric.js JSON在同一次render调用中生成
|
||
- 使用完全相同的参数、计算逻辑、渲染上下文
|
||
- 消除任何可能的差异来源
|
||
|
||
### 技术实现:
|
||
|
||
1. **VibrantTemplate.generate()扩展**:
|
||
```python
|
||
# 新增参数
|
||
generation_result = template.generate(
|
||
content=content,
|
||
images=images,
|
||
generate_fabric_json=True # 启用统一生成
|
||
)
|
||
|
||
# 返回结构
|
||
{
|
||
'png': PIL.Image,
|
||
'fabric_json': Dict,
|
||
'metadata': {
|
||
'gradient_start': int,
|
||
'theme_color': str,
|
||
'elements_count': int
|
||
}
|
||
}
|
||
```
|
||
|
||
2. **渲染上下文共享**:
|
||
- 图像处理参数
|
||
- 渐变起始位置
|
||
- 颜色提取结果
|
||
- 文本布局计算
|
||
- 所有几何计算
|
||
|
||
3. **向后兼容性**:
|
||
- 自动检测模板是否支持新参数
|
||
- 无缝回退到独立生成模式
|
||
- 不影响现有的模板实现
|
||
|
||
### ✅ 已完成:
|
||
- 标准fabric.js JSON格式输出
|
||
- 简化的文本布局(只使用textbox/text)
|
||
- 装饰性图像生成器(按钮、标签、价格背景)
|
||
- 装饰图像上传到七牛云的完整流程
|
||
- fabric.js JSON中占位符URL自动替换
|
||
- 统一1350x1800基础尺寸
|
||
- 端到端的装饰图像处理工作流
|
||
- **VibrantTemplate统一生成架构**
|
||
- **PNG和JSON完全一致的渲染逻辑**
|
||
|
||
### 🔄 进行中:
|
||
- 测试统一生成模式的一致性验证 |