提交后立即返回
提交成功返回 HTTP 202、任务 ID 和访问令牌,客户端无需保持长连接。
支持文件上传、批量图片、远程 URL、Base64、原始二进制、尺寸调整和任务进度查询。网页工具默认异步提交,不让长时间转换占住浏览器请求。
任务提交后会显示队列位置、处理阶段和进度;完成后由受保护的接口下载结果。
提交成功返回 HTTP 202、任务 ID 和访问令牌,客户端无需保持长连接。
任务可以进入异步处理队列,适合批量提交、自动化集成和稍后回访下载。
保存任务 ID 和令牌后,即使网页关闭,也能在保留期内继续查询和下载。
curl -X POST 'https://www.livetops.com/tools/img-api.php?action=submit&lang=zh' \
-F 'image=@photo.jpg' \
-F 'format=webp' \
-F 'quality=82' \
-F 'max_side=1600'
响应为 HTTP 202。access_token 只在创建响应中返回一次,请安全保存,不要写入公开日志。
curl 'https://www.livetops.com/tools/img-api.php?action=status&id=j_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&lang=zh' \
-H 'Authorization: Bearer YOUR_JOB_ACCESS_TOKEN'
curl -L 'https://www.livetops.com/tools/img-api.php?action=download&id=j_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
-H 'Authorization: Bearer YOUR_JOB_ACCESS_TOKEN' \
-o result.webp
# 单图字段 image;批量字段 images[]curl -X POST 'https://www.livetops.com/tools/img-api.php?action=submit' \
-F 'images[]=@a.jpg' \
-F 'images[]=@b.png' \
-F 'format=webp'
{
"image_url": "https://example.com/photo.jpg",
"format": "webp",
"quality": 82,
"max_side": 1600
}
{
"image_urls": [
"https://example.com/a.jpg",
"https://example.com/b.png"
],
"format": "webp",
"quality": 80
}
{
"image_base64": "data:image/png;base64,iVBORw0KGgoAAA...",
"format": "jpeg",
"background": "#ffffff"
}
curl -X POST 'https://www.livetops.com/tools/img-api.php?action=submit&format=png' \
-H 'Content-Type: image/jpeg' \
--data-binary '@photo.jpg'
queued → processing → completed,也可能结束为 partially_completed、failed、cancelled、expired。
{
"success": true,
"request_id": "r_...",
"job": {
"id": "j_...",
"status": "queued",
"stage": "waiting",
"progress": 5,
"poll_after_ms": 2000,
"expires_at": "...",
"links": {"status": "...", "download": "...", "cancel": "..."}
},
"access_token": "..."
}
{
"success": true,
"job": {
"status": "processing",
"stage": "encoding",
"progress": 72,
"queue_position": 0,
"total_items": 3,
"completed_items": 2,
"failed_items": 0,
"download_ready": false
}
}
{
"success": false,
"request_id": "r_...",
"error": {
"code": "FILE_TOO_LARGE",
"message": "...",
"details": {"max_bytes": 25165824}
}
}
客户端应以 error.code 和 HTTP 状态码为主要判断依据,不要依赖可能本地化的 message 文本。progress 是任务阶段进度,并非底层编码器的逐字节精确进度。
async function convertImage(file) {
const form = new FormData();
form.append('image', file);
form.append('format', 'webp');
form.append('quality', '82');
const createdResponse = await fetch('https://www.livetops.com/tools/img-api.php?action=submit', {
method: 'POST', body: form
});
const created = await createdResponse.json();
if (!createdResponse.ok) throw new Error(created.error?.code || 'SUBMIT_FAILED');
const headers = { Authorization: `Bearer ${created.access_token}` };
let job = created.job;
while (!['completed','partially_completed','failed','cancelled','expired'].includes(job.status)) {
await new Promise(r => setTimeout(r, job.poll_after_ms || 2000));
const response = await fetch(job.links.status, { headers, cache: 'no-store' });
const payload = await response.json();
if (!response.ok) throw new Error(payload.error?.code || 'STATUS_FAILED');
job = payload.job;
}
if (!job.download_ready) throw new Error(job.error?.code || job.status);
const result = await fetch(job.links.download, { headers });
if (!result.ok) throw new Error('DOWNLOAD_FAILED');
return await result.blob();
}
import time
import requests
with open("photo.jpg", "rb") as image:
response = requests.post(
"https://www.livetops.com/tools/img-api.php?action=submit",
files={"image": ("photo.jpg", image, "image/jpeg")},
data={"format": "webp", "quality": 82, "max_side": 1600},
timeout=60,
)
response.raise_for_status()
created = response.json()
headers = {"Authorization": f"Bearer {created['access_token']}"}
job = created["job"]
while job["status"] not in {"completed", "partially_completed", "failed", "cancelled", "expired"}:
time.sleep(job.get("poll_after_ms", 2000) / 1000)
status = requests.get(job["links"]["status"], headers=headers, timeout=30)
status.raise_for_status()
job = status.json()["job"]
if not job.get("download_ready"):
raise RuntimeError(job.get("error", {}).get("code", job["status"]))
result = requests.get(job["links"]["download"], headers=headers, timeout=120)
result.raise_for_status()
open("result.webp", "wb").write(result.content)
<?php
$ch = curl_init('https://www.livetops.com/tools/img-api.php?action=submit');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'image' => new CURLFile('/path/photo.jpg', 'image/jpeg', 'photo.jpg'),
'format' => 'webp',
'quality' => 82,
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
]);
$created = json_decode(curl_exec($ch), true, 512, JSON_THROW_ON_ERROR);
curl_close($ch);
$job = $created['job'];
$token = $created['access_token'];
// 按 job.poll_after_ms 轮询 job.links.status,完成后携带 Bearer token 下载。
import { openAsBlob } from 'node:fs';
const form = new FormData();
form.set('image', await openAsBlob('photo.jpg'));
form.set('format', 'webp');
const created = await fetch('https://www.livetops.com/tools/img-api.php?action=submit', { method: 'POST', body: form }).then(r => r.json());
const headers = { Authorization: `Bearer ${created.access_token}` };
// 使用 mime/multipart 创建 image 字段,POST 到 action=submit。
// 保存响应中的 job.id 和 access_token;后续 GET status/download 时设置:
req.Header.Set("Authorization", "Bearer " + accessToken)
// 使用 HttpClient 发送 multipart 请求创建任务。
// 状态与下载请求:
HttpRequest request = HttpRequest.newBuilder(URI.create(statusUrl))
.header("Authorization", "Bearer " + accessToken)
.GET().build();
using var form = new MultipartFormDataContent();
form.Add(new StreamContent(File.OpenRead("photo.jpg")), "image", "photo.jpg");
form.Add(new StringContent("webp"), "format");
var created = await http.PostAsync("https://www.livetops.com/tools/img-api.php?action=submit", form);
// 查询与下载时设置 AuthenticationHeaderValue("Bearer", accessToken)。
multipart 上传会保留原文件名的主文件名,只把扩展名替换为目标格式。例如 aaa.png 转 WebP 后下载为 aaa.webp。服务器磁盘内部仍使用随机名称。
curl -F "image=@aaa.png" -F "format=webp" "https://www.livetops.com/tools/img-api.php?action=submit"
# 完成后的状态响应:job.download_name = "aaa.webp"
# 下载响应:Content-Disposition: attachment; filename*=UTF-8''aaa.webp
批量任务返回 ZIP;ZIP 内按原文件名生成 aaa.webp、bbb.webp,并包含 manifest.json。若转换后重名,会自动变为 aaa-2.webp、aaa-3.webp。状态响应的 items[].original_name、items[].download_name 和 outputs[].download_name 可直接建立输入输出映射。
# 可选:单图自定义结果名;批量时自定义 ZIP 名称
-F "output_name=project-final"
# 也可使用请求头:X-Output-Filename: project-final
# Base64 / 原始二进制没有天然文件名,可选:
input_name=aaa.png
# 或请求头:X-Input-Filename: aaa.png
| 参数 | 类型 / 取值 | 默认值与说明 |
|---|---|---|
format | jpeg, png, webp, avif | webp;实际能力以 capabilities 为准。 |
output_name | string, optional | 自定义下载名称(不要依赖扩展名)。单图生成 output_name.目标格式;批量时用作 ZIP 名称,ZIP 内图片仍按原文件名恢复。也可发送 X-Output-Filename。 |
quality | integer 1–100 | 82;用于 JPEG、WebP、AVIF。 |
png_level | integer 0–9 | 6;PNG 无损压缩等级。 |
width, height | integer | 只提供一个时保持宽高比;同时提供时由 fit 决定。 |
max_side | integer | 在未明确提供宽高时限制最长边。 |
fit | contain, cover, crop, stretch | contain;控制目标画布适配方式。 |
no_upscale | boolean | true;避免放大小图。 |
max_size_kb | integer 1–10240 | 对 JPEG、WebP、AVIF 尝试控制最大体积,不保证字节完全相等。 |
background | #RRGGBB | #ffffff;透明图转 JPEG 或 contain 留白背景。 |
auto_orient | boolean | true;根据 JPEG EXIF 纠正方向。 |
rotate | 90, 180, 270, -90 | 顺时针旋转。 |
flip_h, flip_v | boolean | 水平或垂直翻转。 |
grayscale | boolean | 灰度转换。 |
| 用途 | 方法与接口 | 说明 |
|---|---|---|
| 异步提交 | POST ?action=submit / ?action=jobs | HTTP 202 |
| 查询任务 | GET ?action=status&id=... / ?action=job&id=... | Bearer token |
| 下载结果 | GET|HEAD ?action=download&id=... | Bearer token |
| 取消任务 | POST ?action=cancel&id=... / DELETE ?action=job&id=... | Bearer token |
| 额度查询 | GET ?action=quota | 返回当前调用额度和服务是否可接收新任务。 |
| 能力查询 | GET ?action=capabilities | 返回支持格式、公开功能、默认值和开发者相关限制。 |
| 同步兼容代码 | POST ?action=convert / ?action=batch | 当前公开服务默认关闭;发送 Prefer: respond-async 可进入异步流程。 |
200 查询或下载成功;202 任务已接受;400 请求错误;403 凭证或输入被拒绝;409 结果尚未准备;410 结果已过期;413 体积或像素超限;415 格式不支持;429 频率或图片额度超限;503 服务容量或处理能力暂时不可用。
对 429 和 503 优先读取 Retry-After。状态查询遵循 poll_after_ms。不要自动重试 400、403、413、415;网络失败可采用 1、2、4、8 秒的有限指数退避。
SERVICE_CAPACITY_REACHED · DOWNLOAD_TEMPORARILY_UNAVAILABLE · TOO_MANY_PENDING_JOBS · QUEUE_BUSY · FILE_TOO_LARGE · INVALID_IMAGE · UNSUPPORTED_OUTPUT_FORMAT · RESULT_EXPIRED
普通请求、图片处理和下载分别设有公平使用限制。当前可公开查询的准确数值以 capabilities 与 quota 接口返回为准。
服务繁忙或达到当前公共容量时可能暂缓接收新任务。请读取标准错误对象和 Retry-After,不要高频重复提交。
任务凭证可用于稍后查询和下载。完成结果当前保留约 7 天;请以 expires_at 和 capabilities 返回值为准。
队列位置仅供参考。不同任务图片尺寸、输出格式和远程下载速度不同,实际完成顺序和耗时可能变化。客户端应持久保存任务凭证,不要依赖浏览器页面持续打开。
文件只用于完成转换;原始输入处理后默认删除,结果在有限保留期后清理。
任务 ID 不是完整凭证。查询、取消和下载还需要创建时返回的访问令牌。
服务会检查图片内容、尺寸、像素和资源消耗;超限或无效请求返回标准错误。
公共转换接口默认不需要 API Key。异步任务会返回仅用于该任务查询、取消和下载的随机访问令牌。
提交接口立即返回 HTTP 202、任务 ID 和访问令牌。客户端轮询状态接口,完成后再通过受保护的下载接口获取结果。
不会。上传文件仅用于处理,结果在有限保留期后自动清理;准确期限请查看 capabilities 返回值。
输入能力取决于服务器 GD,通常支持 JPG、PNG、WebP、GIF、BMP 和 AVIF;输出支持 JPG、PNG、WebP,以及环境可用时的 AVIF。
支持 multipart 多文件、JSON 远程 URL 列表、Base64/Data URL 和原始二进制请求体。批量结果以 ZIP 下载。
当前公开服务默认关闭同步执行,但保留兼容代码。开发者应使用异步提交、状态查询和结果下载流程。
请读取标准错误码与 Retry-After,并在建议时间后重试。已经创建的任务仍可通过状态接口确认结果是否可用。