HiAPI
博客

教程

如何通过 hiapi API 使用 gpt-image-2 图生图

一份可直接运行的代码配方,教你如何在 hiapi 上调用 gpt-image-2 的图生图端点:请求信封、参考图与 aspect_ratio 参数、轮询与回调的取舍,以及可直接复制粘贴的 curl、Python 和 Node.js 示例。

2026年11月3日
如何通过 hiapi API 使用 gpt-image-2 图生图

本配方将手把手演示如何通过 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 通过同一套异步任务接口暴露所有图像模型:

  1. POST /v1/tasks —— 提交任务,返回一个 taskId。
  2. 要么轮询 GET /v1/tasks/{taskId} 直到 status === "success",要么 提供 callback.url,通过 webhook 接收最终结果。
  3. 从 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 完成存储 + 通知工作。

错误处理

实践中你会遇到三种失败模式:

  1. 401 permission_denied 附带 "This API key cannot use the selected model." —— 该密钥未授权使用 gpt-image-2/image-to-image。请在 hiapi 控制台检查,并在定价页面确认该模型在你的套餐内。
  2. 400 附带 additional properties not allowed —— 你发送了特定模型不接受的字段(例如用 size 代替 aspect_ratio)。错误消息会指明违规键名;移除它并重试。
  3. status: "fail" 在轮询时附带 data.error 对象 —— 模型本身拒绝了输入(不安全内容、参考 URL 不可达等)。将 error.code 和 error.message 记录到日志,不要盲目自动重试。

始终为 POST /v1/tasks 调用设置请求超时(30 秒足够 —— 它会快速返回 taskId),并为轮询循环或 webhook 接收路径设置单独的、更长的超时。

相关链接

常见问题

问: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 等)。

问:每张图片成本多少? 答:取决于你的套餐和分辨率。当前每次调用费用见定价页面。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档