HiAPI
ブログ

チュートリアル

APIで正確なサイズの商品画像を生成する:アスペクト比とECプラットフォーム仕様

Jul 9, 2026
APIで正確なサイズの商品画像を生成する:アスペクト比とECプラットフォーム仕様

販売チャネルごとに商品画像に求められるサイズは異なります。Amazonは白背景の大きな正方形画像、Instagramは4:5の縦構図、Pinterestは2:3のPin画像、そして自社ストアのトップページヒーロービジュアルには超ワイド画像が必要です。本ガイドでは、hiapi APIを使ってこれらすべてのサイズの画像をプログラムで生成する方法を紹介します——gpt-image-2とwan2.7-imageを使用し——毎回正確に目標ピクセルサイズに合わせる方法を解説します。

前提条件:hiapi APIキー(コンソールで作成)と、curlまたはPython。総コストは選択するモデルと解像度によって異なります——料金を参照してください。

APIにおける画像サイズの実際の仕組み

まず最も混乱しやすい点から説明します:hiapiの画像モデルはピクセルサイズを受け付けません。 size、width、heightフィールドは存在しません。もし渡そうとすると、APIは明確にエラーを返します:

{
  "code": 400,
  "error_code": "INVALID_REQUEST",
  "message": "invalid input: <root>: additional properties 'size' not allowed"
}

代わりに、サイズはinput内の2つのフィールドで制御します:

  • aspect_ratio —— 画面の形状。各モデル固有の固定リストから選択します。
  • resolution —— 出力ティア:"1K"、"2K"、"4K"(長辺はおおよそ1024 / 2048 / 4096ピクセル。正確なピクセル数は比率によって異なるため、受け取ったファイルを必ず確認してください)。

以下は本ガイドで扱う2つのモデルが実際に受け付けるパラメータです(オンラインAPIで検証済み):

gpt-image-2 wan2.7-image/text-to-image
prompt 必須 必須
aspect_ratio auto、1:1、3:2、2:3、4:3、3:4、5:4、4:5、16:9、9:16、2:1、1:2、3:1、1:3、21:9、9:21 —— 計16値 1:1、16:9、4:3、21:9、3:4、9:16、8:1、1:8 —— 計8値
resolution 1K、2K、4K 1K、2K、4K
追加機能 画像to画像バリアント(gpt-image-2/image-to-image) 再現用のseed(整数)
ピクセルsize / n 非対応 非対応

実際の違いは次の点にあります:gpt-image-2はソーシャルおよびECプラットフォームのフォーマットに必要な比率を網羅しており(4:5、2:3、5:4はgpt-image-2固有)、一方wan2.7-imageは8:1/1:8の超ワイドバナーを追加しており、他の比率リストにはない——細長いプロモーションバナーに適しており——4Kスタジオ撮影風画像の定番の選択肢でもあります。

したがって、サイズを正確に制御するには2段階のレシピになります:

  1. 一致するアスペクト比で生成し、長辺が目標サイズ以上になる最小の解像度ティアを選択します(後で縮小し、絶対に拡大しない)。
  2. 返却されたファイルをローカルで正確な目標ピクセルに調整します——Pillowの1行コードです。

ECプラットフォーム仕様早見表

以下は一般的に公開されている要件をAPIパラメータにマッピングしたものです:

チャネル 典型的な目標 aspect_ratio resolution モデル備考
Amazonメイン画像 長辺 ≥1000ピクセル(1600ピクセル以上でズーム有効)、正方形、純白背景 1:1 2K どちらも可
Shopify商品ページ 推奨 2048×2048 1:1 2K どちらも可
Instagramフィード(縦構図) 1080×1350 4:5 2K gpt-image-2のみ
Stories / Reels / TikTok 1080×1920 9:16 2K どちらも可
Pinterest Pin 1000×1500 2:3 2K gpt-image-2のみ
Etsy商品リスト 推奨 2700×2025 4:3 4K どちらも可(4Kティアが必要)
ウェブサイトヒーローバナー 例:幅2560ピクセル 21:9 4K どちらも可
細長いプロモーションバナー 超ワイド 8:1 2K/4K wan2.7-imageのみ

(各プラットフォームの仕様は変わります。これらのピクセル目標は一般的な公開推奨値として扱い、各プラットフォームの最新ドキュメントで確認してください。)

最小動作例(curl)

すべては統一された非同期タスクエンドポイント経由で実行されます:POST /v1/tasksで作成し、GET /v1/tasks/<id>でポーリングします。2KティアでAmazon風の正方形画像を作成する例:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/text-to-image",
    "input": {
      "prompt": "Studio product photo of a stainless steel water bottle on a pure white background, centered, soft shadow, e-commerce catalog style",
      "aspect_ratio": "1:1",
      "resolution": "2K"
    }
  }'

レスポンス内のタスクIDはdata.taskIdにあります。それをポーリングします:

curl -s https://api.hiapi.ai/v1/tasks/TASK_ID \
  -H "Authorization: Bearer sk-YOUR_KEY"

data.statusが"success"になるまでポーリングします(または"fail"。詳細はdata.errorの下にあります)。画像URLはdata.output[0].urlにあります。このURLは期限切れになります(出力オブジェクトにはexpireAtが付きます)。そのため、すぐにダウンロードして自分のストレージに再ホストしてください——商品リストで直接ホットリンクしないでください。

本番スクリプト:1つの商品、すべてのチャネル、正確なピクセル

このバッチスクリプトは、すべてのタスクを事前に作成し(プラットフォーム上で並行して実行されます)、1つずつ完了までポーリングし、その後Pillowで正確な目標サイズに調整します。ImageOps.fitは1回の呼び出しで縮小とわずかなクロップの両方を処理します。

import os
import time
from io import BytesIO

import requests
from PIL import Image, ImageOps

API = "https://api.hiapi.ai/v1"
HDRS = {
    "Authorization": f"Bearer {os.environ['HIAPI_KEY']}",
    "Content-Type": "application/json",
}

# チャネル -> 生成パラメータ + 正確なピクセル目標
SPECS = {
    "amazon-main":    {"model": "gpt-image-2/text-to-image", "aspect_ratio": "1:1",  "resolution": "2K", "px": (1600, 1600)},
    "shopify":        {"model": "gpt-image-2/text-to-image", "aspect_ratio": "1:1",  "resolution": "2K", "px": (2048, 2048)},
    "instagram-feed": {"model": "gpt-image-2/text-to-image", "aspect_ratio": "4:5",  "resolution": "2K", "px": (1080, 1350)},
    "story-reel":     {"model": "gpt-image-2/text-to-image", "aspect_ratio": "9:16", "resolution": "2K", "px": (1080, 1920)},
    "pinterest-pin":  {"model": "gpt-image-2/text-to-image", "aspect_ratio": "2:3",  "resolution": "2K", "px": (1000, 1500)},
    "etsy-listing":   {"model": "wan2.7-image/text-to-image", "aspect_ratio": "4:3",  "resolution": "4K", "px": (2700, 2025)},
    "hero-banner":    {"model": "wan2.7-image/text-to-image", "aspect_ratio": "21:9", "resolution": "4K", "px": (2560, 1097)},
}

PROMPT = (
    "Studio product photo of a stainless steel water bottle on a pure white "
    "background, centered, soft shadow, high detail, e-commerce catalog style"
)


def create_task(model: str, prompt: str, aspect_ratio: str, resolution: str) -> str:
    body = {
        "model": model,
        "input": {"prompt": prompt, "aspect_ratio": aspect_ratio, "resolution": resolution},
    }
    data = requests.post(f"{API}/tasks", json=body, headers=HDRS, timeout=60).json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id


def wait_task(task_id: str, timeout_s: int = 600) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        data = requests.get(f"{API}/tasks/{task_id}", headers=HDRS, timeout=30).json()
        task = data.get("data") or {}
        if task.get("status") == "success":
            return task["output"][0]["url"]
        if task.get("status") == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task {task_id} failed: {err.get('code')} {err.get('message')}")
        time.sleep(5)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")


def save_exact(url: str, px: tuple, path: str) -> None:
    # 出力URLは期限切れになる —— すぐにダウンロードし、正確なピクセルにフィットさせる。
    raw = requests.get(url, timeout=120).content
    img = Image.open(BytesIO(raw))
    ImageOps.fit(img, px, Image.LANCZOS).save(path)


if __name__ == "__main__":
    # まずすべてのタスクを作成:タスクはプラットフォーム上で並行して実行される
    tasks = {
        name: create_task(s["model"], PROMPT, s["aspect_ratio"], s["resolution"])
        for name, s in SPECS.items()
    }
    for name, task_id in tasks.items():
        url = wait_task(task_id)
        save_exact(url, SPECS[name]["px"], f"{name}.png")
        print(f"{name}: {SPECS[name]['px']} -> {name}.png")

残りの部分を書き直す場合でも、そのまま踏襲する価値のある2つの詳細があります:

  • 解像度ティアを選ぶ際は長辺 ≥ 目標を保証する。 Etsyの2700ピクセル目標は2Kティアの約2048ピクセルを超えるため、4Kで生成してから縮小します。LANCZOSでの縮小は商品カタログ用途では視覚的に無損失ですが、拡大はそうではありません。
  • タスク作成後すぐにtaskIdを永続化する。 ワーカーがクラッシュした場合、復旧時にタスクを再作成するのではなく、保存されたIDをポーリングします——再作成すると2枚目の画像が生成され(課金されます)。

代わりに承認済みメイン画像を再レイアウトする

多くの場合、7枚の独立した生成画像は不要です——必要なのは同一の承認済み商品画像を各チャネル向けに再構成することです。それがgpt-image-2/image-to-imageです:input_urls(公開アクセス可能な画像URLの配列)とpromptが必要で、同じ16個のaspect_ratio値を受け付けます:

{
  "model": "gpt-image-2/image-to-image",
  "input": {
    "prompt": "Extend the background naturally to fill the new frame; keep the product unchanged and centered",
    "input_urls": ["https://your-cdn.com/hero-shot.png"],
    "aspect_ratio": "9:16"
  }
}

タスクライフサイクルは同じで、最後に同様の正確なピクセル処理を行います。完全な実践手順はHow to Use gpt-image-2 Image-to-Image via the hiapi APIを参照してください。

本番運用の注意点

ポーリングの代わりにコールバックを使う。 サーバーサイドでは、タスク作成時にトップレベルのcallbackを渡すことで、ポーリングループを完全に省略できます:

{
  "model": "gpt-image-2/text-to-image",
  "input": {"prompt": "...", "aspect_ratio": "1:1", "resolution": "2K"},
  "callback": {"url": "https://yourapp.com/hooks/hiapi", "when": "final"}
}

最終ステータスで1回POSTを受け取ります。コールバックは真実の情報源ではなくシグナルとして扱ってください:アクションを起こす前にGET /v1/tasks/<id>を再取得し、taskIdで重複排除します。コールバックがまったく届かない場合は、Why your hiapi task callback isn't firingを参照してください。

エラーハンドリング。 認証失敗は401 permission_deniedを返します——まずAuthorization: Bearer sk-...ヘッダーを確認してください。バリデーション失敗は400を返し、error_code: "INVALID_REQUEST"が付きます。そのメッセージは特に有用で、許可される正確な値を列挙します(上記の比率表はこうして検証されました)。入力スキーマはモデルによって異なります——wan2.7-imageはseedを受け付けますが、gpt-image-2は受け付けません。一部の高速モデルはresolutionを完全に拒否します——そのためフィールドをハードコードする前に各モデルのページを確認してください。

コスト管理。 価格はモデルと解像度ティアによって変わります。プロンプトを反復する際は1Kで生成し、最終稿を出すときだけ2K/4Kに切り替えてください——現在の1枚あたりの価格は料金ページにあります。

関連記事

よくある質問

リクエストで1080×1350のような正確なピクセルサイズを渡せますか? いいえ。size、width、heightは400で拒否されます(additional properties ... not allowed)。一致するaspect_ratioと、目標以上のresolutionティアで生成し、その後ローカルで正確なピクセルに縮小してください——上記のPillow1行コードです。

Amazonメイン画像にはどの設定を使うべきですか? aspect_ratio: "1:1"、resolution: "2K"、その後目標サイズに調整します(1600×1600が信頼できるデフォルトです——1000ピクセルのズーム閾値を超えています)。Amazonメイン画像は純白背景も必須なので、プロンプトに含め、出品前に出力を確認してください。

目標の比率がリストにない場合(例:1.91:1のリンク広告フォーマット)はどうすればよいですか? 目標を完全にカバーする、最も近いより広いまたは等しい比率で生成します——1.91:1なら2:1または16:9が使えます——その後中央でクロップします。スクリプトのImageOps.fitはまさにこれを行います:1回の呼び出しではみ出した部分のクロップとサイズ調整を完了します。

真の4K商品画像を得るにはどうすればよいですか? 両モデルでresolution: "4K"を設定します。wan2.7-imageは4Kスタジオ撮影風画像の定番の選択肢です。プロンプトパターンはWan 2.7 ECガイドを参照してください。

生成された画像URLは期限切れになりますか? はい——各出力にはexpireAtが付きます。タスク成功後すぐにファイルをダウンロードし、自分のストレージに再ホストしてください。タスク出力URLを商品リストに貼り付けないでください。

1回のリクエストで複数のバリアントを生成できますか? いいえ——これらのモデルにはnパラメータがありません。画像ごとにタスクを作成します。タスクは並行して実行されるため、ループでバッチ処理しても(上記スクリプトのように)実際の速度は同じです。wan2.7-imageではseedを変えることで、同じプロンプトの制御されたバリアントを得られます。

永続的なAIアーティファクトで開発を始める

APIキーを取得して、タスクベースの1つのAPIで画像・動画・音声モデルを呼び出せます。

APIドキュメントを読む