九宫格切图API实战:自动裁切与多图输出
·
适用场景与设计动机
在社交媒体分享、电商主图展示、个人博客封面等场景中,将一张大图切成均匀的九宫格(或四宫格、十六宫格)可以显著提升视觉张力和互动率。传统的做法是使用Photoshop手动切片,或编写本地脚本依赖OpenCV。但这类方案存在环境依赖重、无法服务化、批量处理效率低等问题。九宫格切图API将裁切逻辑封装为RESTful接口,开发者只需传入图片即可获得切好的小图列表或ZIP包,实现零本地依赖的自动化处理。
接口能力边界
- 宫格类型:支持 2×2、3×3、4×4(通过参数
grid控制) - 图片源:multipart 文件上传、base64 数据、公网图片URL(三选一)
- 输入格式:jpg/png/webp/gif(非动图)
- 留白像素:0-20px,通过
gap设置切片间间距 - 输出方式:
base64:返回 JSON 对象,每个切片的 base64 数据 + data URLzip:直接返回application/zip二进制流,包含按序号命名的文件
- 速率限制:QPS = 2/s,超过后返回 429 状态码
- 图片尺寸限制:以文档更新为准,建议单边像素不超过 4000px
鉴权方式与请求头
API 使用 API Key 进行身份校验,通过 X-API-Key 请求头传递。若未提供,请求将返回 401。
X-API-Key: your_api_key_here
生产环境建议将 Key 存储在环境变量中,避免硬编码。
请求参数详解
请求方式:POST 至 https://v1.apizero.cn/api/nine-grid-cutter
公共参数(JSON Body 或 multipart 字段)
| 参数名 | 类型 | 是否必需 | 默认值 | 说明 |
|---|---|---|---|---|
grid |
number | 否 | 3 | 宫格数:2、3、4 |
gap |
number | 否 | 0 | 切片间留白像素,范围 0-20 |
output |
string | 否 | base64 | 输出格式:base64 或 zip |
图片源参数(三选一,必须提供其中一个)
- file (multipart):使用
multipart/form-data上传文件,字段名file,支持图片格式。 - image_base64 (string):图片的 base64 编码(可包含
data:image/png;base64,前缀或不含)。 - image_url (string):公网图片直链(http/https),需确保图片可公开访问。
当使用 JSON 格式请求时,只能选择 image_base64 或 image_url;当使用 multipart 时,file 字段与其余参数一同作为表单字段。
curl 接入示例
方式一:使用公网图片 URL(JSON POST)
curl -sS -X POST \
-H "X-API-Key: $APIZERO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"grid": 3,
"gap": 2,
"output": "base64",
"image_url": "https://example.com/your-image.jpg"
}' \
"https://v1.apizero.cn/api/nine-grid-cutter"
替换 $APIZERO_API_KEY 为你的真实 Key,并将 image_url 改为有效图片链接。返回 JSON 包含 9 个切片的 base64 数据。
方式二:使用 multipart 上传本地文件
对于本地图片,推荐使用 multipart 方式(无需额外编码):
curl -sS -X POST \
-H "X-API-Key: $APIZERO_API_KEY" \
-F "file=@/path/to/photo.jpg" \
-F "grid=3" \
-F "gap=0" \
-F "output=zip" \
"https://v1.apizero.cn/api/nine-grid-cutter" -o slices.zip
该命令将返回一个 ZIP 文件,以 -o slices.zip 保存到本地,所有切片按顺序命名(1.png, 2.png, ..., 9.png)。
Python 代码接入示例
import requests
import base64
API_URL = "https://v1.apizero.cn/api/nine-grid-cutter"
API_KEY = "your_api_key_here"
# 方式一:上传本地文件
with open("photo.jpg", "rb") as f:
files = {"file": ("photo.jpg", f, "image/jpeg")}
data = {"grid": 3, "gap": 0, "output": "base64"}
headers = {"X-API-Key": API_KEY}
resp = requests.post(API_URL, files=files, data=data, headers=headers)
# 方式二:使用图片 URL
# payload = {"grid": 3, "gap": 0, "output": "base64",
# "image_url": "https://example.com/image.jpg"}
# headers["Content-Type"] = "application/json"
# resp = requests.post(API_URL, json=payload, headers=headers)
if resp.status_code == 200:
result = resp.json()
if result["code"] == 0:
pieces = result["data"]["pieces"]
print(f"共 {len(pieces)} 切片,每个尺寸 {pieces[0]['size']}")
# 保存第一个切片
first_img = base64.b64decode(pieces[0]["base64"])
with open("slice_1.png", "wb") as out:
out.write(first_img)
else:
print("错误:", result["msg"])
else:
print("HTTP 错误:", resp.status_code, resp.text)
返回字段解读
成功响应(HTTP 200)示例:
{
"code": 0,
"msg": "成功",
"request_id": "abc123",
"data": {
"original_size": "1080x1920",
"square_side": 1080,
"grid": "3x3",
"gap": 0,
"cell_size": "360x360",
"total": 9,
"source": "multipart",
"pieces": [
{
"index": 1,
"size": "360x360",
"base64": "iVBORw0K...",
"data_url": "data:image/png;base64,iVBORw0K..."
},
...
]
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
code |
int | 业务状态码,0 表示成功 |
msg |
string | 业务提示信息 |
request_id |
string | 请求唯一标识,便于排查 |
data.original_size |
string | 原始图片尺寸 |
data.square_side |
int | 裁切后的正方形边长(px) |
data.grid |
string | 宫格标识,如 "3x3" |
data.gap |
int | 实际使用的留白值 |
data.cell_size |
string | 每个小图尺寸 |
data.total |
int | 总切片数(grid×grid) |
data.source |
string | 图片来源:multipart / base64 / url |
data.pieces[] |
array | 切片列表,按左到右、上到下顺序排列 |
pieces[].index |
int | 切片序号(1 开始) |
pieces[].size |
string | 切片尺寸 |
pieces[].base64 |
string | 切片图片的 base64 编码(不含 data URL 前缀) |
pieces[].data_url |
string | 可直接用于 <img src> 的 data URL |
当 output=zip 时,响应体为二进制流,HTTP 头包含 Content-Type: application/zip,无 JSON 数据。
常见错误与排查
| HTTP 状态码 | 可能原因 | 排查思路 |
|---|---|---|
| 400 | 参数缺失或格式错误 | 检查是否提供了且仅提供了一种图片源;检查 grid 是否在 2/3/4 范围内;gap 是否 0-20 |
| 401 | API Key 无效或缺失 | 确认 X-API-Key 头已正确添加,且 Key 未过期 |
| 413 | 图片体积过大 | 压缩图片至 10MB 以下再试;或使用 URL 方式(需服务端可访问) |
| 415 | 不支持的图片格式 | 确保文件后缀或 base64 对应 jpg/png/webp/gif |
| 429 | 请求频率超过限制 | 降低并发,或加入本地重试队列(间隔 500ms 以上) |
| 500 | 服务端内部错误 | 将 request_id 提供给技术支持 |
常见业务错误码(code 非 0):
-1:未知错误1001:图片下载失败(URL 不可达或超时)1002:图片解码失败(可能文件损坏或非图片)1003:图片尺寸过大(超过服务端限制)
工程化注意事项
- QPS 控制:接口限速 2/s,若需要批量处理多张图片,建议使用本地队列 + 间隔 500ms 的定时器,或使用异步任务池,防止触发限流。
- 输出模式选择:当切片数量多(如 4×4 共 16 张)且图片较大时,base64 数据会膨胀约 33%,单次响应体可能超过 10MB。此时推荐使用
zip模式,客户端接收二进制流后直接解压,网络传输效率更高。 - 图片预处理:API 内部会将图片居中裁切为正方形,再等分宫格。如果原图宽高比差异大,裁切后会丢失部分内容。建议在上传前自行确保主体在画面中心,或先对图片做手动裁剪。
- base64 存储:若需长期缓存切片,可将 base64 字符串存入数据库(需注意字段长度),或解码为二进制后存储到对象存储。
data_url可直接用于前端渲染,但不宜大量拼接。 - 错误重试策略:对于 5xx 错误,可重试最多 3 次,间隔指数退避(1s, 2s, 4s)。4xx 错误通常不需要重试,应检查参数。
- 安全考虑:使用
image_url时,确保 URL 来源可信,避免 SSRF 风险。建议对传入 URL 做域名白名单校验。
参考文档
- 官方文档页:https://apizero.cn/aidocs/nine-grid-cutter
- 原始接口文档(Markdown):https://apizero.cn/aidocs/nine-grid-cutter/raw.md
更多推荐



所有评论(0)