fix: harden compression boundaries and target search

This commit is contained in:
237899745
2026-07-25 12:23:35 +08:00
parent 0ff9eae56d
commit 61fa9cb820
9 changed files with 787 additions and 169 deletions

View File

@@ -272,13 +272,19 @@ Idempotency-Key: <key> # 建议
| 字段 | 类型 | 必填 | 说明 |
|---|---|---:|---|
| `file` | File | 是 | 图片文件 |
| `compression_rate` | Integer | 否 | 压缩率 1-100JPEG/WebP/AVIF 以该比例为体积上限,无损格式为尽力优化100 表示不压缩;优先级高于 `level` |
| `compression_rate` | Integer | 否 | 压缩率 1-100JPEG/WebP/AVIF 以该比例为体积上限,无损格式为尽力优化同格式且不缩放时100 保留原始编码;优先级高于 `level` |
| `level` | String | 否 | `high` / `medium` / `low`(兼容参数,默认 `medium` |
| `output_format` | String | 否 | 输出格式:`png/jpeg/webp/avif/gif/bmp/tiff/ico`默认保持原格式ICO 自动等比缩至 256x256 边界) |
| `max_width` | Integer | 否 | 最大宽度(等比缩放) |
| `max_height` | Integer | 否 | 最大高度(等比缩放) |
| `target_size_bytes` | Integer | 否 | 目标体积(字节),仅 `jpeg/webp/avif` 输出支持;会优先保清晰度并在必要时小幅缩放 |
| `preserve_metadata` | Boolean | 否 | 是否保留元数据(默认 `false` |
| `max_width` | Integer | 否 | 大于 0 的最大宽度(等比缩放) |
| `max_height` | Integer | 否 | 大于 0 的最大高度(等比缩放) |
| `target_size_bytes` | Integer | 否 | 不小于 1024 的目标体积(字节),仅 `jpeg/webp/avif` 输出支持;不能与 `compression_rate` 同时指定 |
| `preserve_metadata` | Boolean | 否 | 是否保留 EXIF/ICC(默认 `false`;元数据输出仅支持 `jpeg/png/webp` |
处理约束:
- 动画 GIF/APNG/WebP/AVIF 不会静默截取首帧,而是返回 `400 UNSUPPORTED_FORMAT`
- EXIF 方向会先应用到像素,再移除或归一化方向标记;透明图片转 JPEG 时以白色合成背景。
- 目标体积搜索优先保持原分辨率,必要时在清晰度保护范围内缩放;仍无法达到时返回 `400 INVALID_REQUEST`,不会把超出目标的文件作为成功结果。
- `compression_rate=100` 只有在同格式且未指定缩放时属于免计量原样请求;格式转换或缩放后若体积变小,正常计 1 次。
响应:
```json
@@ -340,7 +346,7 @@ Idempotency-Key: <key> # 建议
| 字段 | 类型 | 必填 | 说明 |
|---|---|---:|---|
| `files[]` | File[] | 是 | 图片文件数组(上限由套餐决定) |
| `compression_rate` | Integer | 否 | 压缩率 1-100JPEG/WebP/AVIF 以该比例为体积上限,无损格式为尽力优化100 表示不压缩;优先级高于 `level` |
| `compression_rate` | Integer | 否 | 压缩率 1-100JPEG/WebP/AVIF 以该比例为体积上限,无损格式为尽力优化同格式且不缩放时100 保留原始编码;优先级高于 `level` |
| `level` | String | 否 | `high` / `medium` / `low`(兼容参数) |
| `output_format` | String | 否 | 输出格式:`png/jpeg/webp/avif/gif/bmp/tiff/ico`(默认保持原格式) |
| `preserve_metadata` | Boolean | 否 | 是否保留元数据(默认 `false` |