教程
如何通过 hiapi API 使用 gpt-image-2 图生图
一份可直接运行的代码配方,教你如何在 hiapi 上调用 gpt-image-2 的图生图端点:请求信封、参考图与 aspect_ratio 参数、轮询与回调的取舍,以及可直接复制粘贴的 curl、Python 和 Node.js 示例。
本配方将手把手演示如何通过 hiapi 统一任务 API 调用 gpt-image-2 的图生图模式。你将获得一个可直接运行的 curl 示例、一个可直接嵌入后端的 Python 脚本、一个适用于无服务器场景的 Node.js 版本,以及真正重要的参数和生产环境中容易踩坑的细节。
读完本文,你将拥有一个脚本:它接收参考图 URL 和提示词,返回一个生成的图片 URL,你可以直接下载,或交给你的存储层处理。
准备工作
- 一个 hiapi 账号和 API 密钥。可在 hiapi 控制台获取。
- 一张托管在公开 HTTPS URL 上的参考图(或 base64 data URL —— 两者均可)。
- 一段文本提示词,描述你希望模型对该参考图做什么。
就这些。无需安装 SDK —— hiapi 就是 HTTP + JSON,任何能发 POST 请求的语言都可以用。
想先了解纯文生图?请参阅 如何使用 hiapi API 生成图片。下面的模式是相同的异步任务流程,只是多了一个
image字段。
最小可用调用
hiapi 通过同一套异步任务接口暴露所有图像模型:
POST /v1/tasks—— 提交任务,返回一个taskId。- 要么轮询
GET /v1/tasks/{taskId}直到status === "success",要么 提供callback.url,通过 webhook 接收最终结果。 - 从
data.output[0].url读取图片 URL 并下载或存储。
curl
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": "transform the subject into a watercolor painting, soft pastel palette",
"image": "https://example.com/reference.jpg",
"aspect_ratio": "1:1",
"resolution": "1K"
}
}'
立即返回的响应会给你任务 id:
{ "data": { "taskId": "task_01HXXXX..." } }
然后轮询结果:
curl https://api.hiapi.ai/v1/tasks/task_01HXXXX... \
-H "Authorization: Bearer sk-YOUR_KEY"
任务就绪后,响应如下所示:
{
"data": {
"status": "success",
"output": [{ "url": "https://cdn.hiapi.ai/...png", "expireAt": "..." }]
}
}
output[0].url 是短期有效的(注意 expireAt),因此请立即下载或重新上传到你自己的存储 —— 切勿向最终用户提供热链接。
真正重要的参数
| 字段 | 类型 | 说明 |
|---|---|---|
model |
string | 使用裸 id gpt-image-2/image-to-image。不要加 models/ 前缀。 |
input.prompt |
string | 你希望对参考图应用的变换。 |
input.image |
string | HTTPS URL 或 data:image/...;base64,... URL。 |
input.aspect_ratio |
string | 取值之一:1:1、3:2、2:3、4:3、3:4、5:4、4:5、16:9、9:16、21:9 或 auto。 |
input.resolution |
string | 1K、2K 或 4K。默认 1K。 |
两个重要行为:
- 部分 hiapi 模型仅接受
aspect_ratio(不带resolution);其他模型则需要像素尺寸。gpt-image-2/image-to-image 接受上文所示的aspect_ratio+resolution组合 —— 不要在这里传size: "1024x1024"。 image字段是参考图。如果你传 base64 data URL,请确保 payload 低于你平台的请求体限制(几 MB 没问题,多兆字节的图片应先上传再以 URL 传入)。
生产级 Python 脚本
此版本带截止时间处理轮询,并在失败时干净退出:
import os
import time
import requests
API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
def submit(prompt: str, image_url: str, aspect_ratio: str = "1:1") -> str:
payload = {
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": prompt,
"image": image_url,
"aspect_ratio": aspect_ratio,
"resolution": "1K",
},
}
r = requests.post(API, headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()["data"]["taskId"]
def wait(task_id: str, timeout_s: int = 300, interval_s: int = 5) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=20)
r.raise_for_status()
task = r.json()["data"]
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(interval_s)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = submit(
prompt="transform the subject into a watercolor painting, soft pastel palette",
image_url="https://example.com/reference.jpg",
)
print("task:", task_id)
print("url:", wait(task_id))
使用 HIAPI_API_KEY=sk-... python recipe.py 运行。
Node.js(fetch,无依赖)
const API = "https://api.hiapi.ai/v1/tasks";
const TOKEN = process.env.HIAPI_API_KEY;
const headers = {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
};
async function submit(prompt, imageUrl, aspectRatio = "1:1") {
const r = await fetch(API, {
method: "POST",
headers,
body: JSON.stringify({
model: "gpt-image-2/image-to-image",
input: { prompt, image: imageUrl, aspect_ratio: aspectRatio, resolution: "1K" },
}),
});
const data = await r.json();
if (!r.ok) throw new Error(JSON.stringify(data));
return data.data.taskId;
}
async function wait(taskId, timeoutMs = 300000, intervalMs = 5000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const r = await fetch(`${API}/${taskId}`, { headers });
const task = (await r.json()).data;
if (task.status === "success") return task.output[0].url;
if (task.status === "fail") throw new Error(JSON.stringify(task.error));
await new Promise((res) => setTimeout(res, intervalMs));
}
throw new Error(`task ${taskId} timed out`);
}
(async () => {
const id = await submit(
"transform the subject into a watercolor painting, soft pastel palette",
"https://example.com/reference.jpg",
);
console.log("task:", id, "\nurl:", await wait(id));
})();
轮询 vs. 回调
每 5 秒轮询一次对于一次性脚本没问题,但它会让一个 worker 在整个任务期间被占用。在真实后端中,你通常想要一个 webhook:
{
"model": "gpt-image-2/image-to-image",
"input": { "prompt": "...", "image": "https://example.com/reference.jpg" },
"callback": { "url": "https://your-app.example.com/api/hiapi-callback", "when": "final" }
}
当任务结算(成功或失败)时,hiapi 会向该 URL POST 与你从 GET /v1/tasks/{id} 得到的相同 payload。请将该处理器视为幂等 —— 重试是可能的 —— 并在信任请求之前进行验证(URL 中携带你自己的签名令牌、检查 Authorization 头等)。
一个干净的模式是:提交任务,以你自己的 job id 为键持久化 taskId,向调用方返回 202 Accepted,让 webhook 完成存储 + 通知工作。
错误处理
实践中你会遇到三种失败模式:
401 permission_denied附带"This API key cannot use the selected model."—— 该密钥未授权使用gpt-image-2/image-to-image。请在 hiapi 控制台检查,并在定价页面确认该模型在你的套餐内。400附带additional properties not allowed—— 你发送了特定模型不接受的字段(例如用size代替aspect_ratio)。错误消息会指明违规键名;移除它并重试。status: "fail"在轮询时附带data.error对象 —— 模型本身拒绝了输入(不安全内容、参考 URL 不可达等)。将error.code和error.message记录到日志,不要盲目自动重试。
始终为 POST /v1/tasks 调用设置请求超时(30 秒足够 —— 它会快速返回 taskId),并为轮询循环或 webhook 接收路径设置单独的、更长的超时。
相关链接
- gpt-image-2 模型页面 —— 能力矩阵和定价层级。
- 所有 hiapi 模型 —— 如果你需要其他图像或视频模型,这里有完整目录。
- API 文档 ——
/v1/tasks及整个接口面的完整参考。 - 如何使用 hiapi API 生成图片 —— 本配方的文生图姊妹篇。
常见问题
问:gpt-image-2/image-to-image 支持多张参考图吗?
答:最小契约使用单个 image 字段。如果你的用例需要多张参考图(例如主体图 + 风格图),请先将它们合成为一张,或查看模型页面了解最新支持的字段。
问:我可以传本地文件而不是 URL 吗?
答:可以 —— 将其编码为 data:image/png;base64,... URL 并作为 input.image 传入。对于超过约 3 MB 的文件,请先上传到你自己的存储并传公开 URL;这样更快且能规避请求体限制。
问:一个任务需要多长时间?
答:大多数 gpt-image-2 图生图任务在 1K 分辨率下 10–30 秒完成。更高分辨率和复杂提示词可能需要更长时间 —— 为保险起见,将轮询超时设为 5 分钟。
问:如何控制输出与参考图的差异程度? 答:在提示词中明确表述。"Keep the subject's pose and composition, only restyle to watercolor" 比 "make this a watercolor" 产生更严格的一致性。gpt-image-2 的图生图模式是提示词驱动的 —— 请求信封中没有单独的 "strength" 滑块。
问:output[0].url 是永久的吗?
答:不是。它带有 expireAt 时间戳(通常几小时)。任务成功后尽快下载字节并上传到你自己的存储(R2、S3 等)。
问:每张图片成本多少? 答:取决于你的套餐和分辨率。当前每次调用费用见定价页面。