HiAPI
Blog

Tutoriale

Genera immagini di prodotto con dimensioni esatte tramite API: rapporti d'aspetto e specifiche delle piattaforme e-commerce

Jul 9, 2026
Genera immagini di prodotto con dimensioni esatte tramite API: rapporti d'aspetto e specifiche delle piattaforme e-commerce

Ogni canale di vendita richiede le tue immagini di prodotto in dimensioni diverse: Amazon vuole immagini quadrate grandi su sfondo bianco, Instagram vuole composizioni verticali 4:5, Pinterest vuole Pin 2:3, e l'immagine principale della homepage del tuo negozio richiede immagini extra-wide. Questa guida spiega come generare immagini a tutte queste dimensioni in modo programmatico con l'API hiapi — usando gpt-image-2 e wan2.7-image — e come arrivare ogni volta esattamente alla dimensione in pixel desiderata.

Prerequisiti: una chiave API hiapi (creata nella console) e curl o Python. Il costo totale dipende dal modello e dalla risoluzione scelti — vedi i prezzi.

Come funzionano davvero le dimensioni delle immagini sull'API

Prima la cosa più confusa: i modelli di immagini su hiapi non accettano dimensioni in pixel. Non esistono i campi size, width o height. Se provi a passarli, l'API te lo dice chiaramente:

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

Invece, le dimensioni sono controllate da due campi in input:

  • aspect_ratio — la forma dell'inquadratura, scelta da un elenco fisso per ogni modello.
  • resolution — il livello di output: "1K", "2K" o "4K" (il lato lungo è approssimativamente 1024 / 2048 / 4096 pixel; il numero esatto di pixel varia in base al rapporto, quindi controlla sempre il file che ricevi).

Di seguito i parametri effettivamente accettati dai due modelli di questa guida (verificati sull'API live):

gpt-image-2 wan2.7-image/text-to-image
prompt obbligatorio obbligatorio
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 valori in totale 1:1, 16:9, 4:3, 21:9, 3:4, 9:16, 8:1, 1:8 — 8 valori in totale
resolution 1K, 2K, 4K 1K, 2K, 4K
Capacità aggiuntive variante image-to-image (gpt-image-2/image-to-image) seed (intero) per la riproducibilità
size / n in pixel non accettati non accettati

La differenza pratica è questa: gpt-image-2 copre i rapporti necessari per i formati social ed e-commerce (4:5, 2:3, 5:4 sono esclusivi di gpt-image-2), mentre wan2.7-image aggiunge banner ultra-wide 8:1/1:8 che nessun altro elenco di rapporti copre — adatti ai banner promozionali stretti — ed è la scelta comune per le immagini in studio 4K.

Quindi, per controllare esattamente le dimensioni, la ricetta è in due passaggi:

  1. Genera con un rapporto d'aspetto corrispondente e scegli il livello di risoluzione minimo con il lato lungo uguale o superiore alla dimensione target (poi riduci, non ingrandire mai).
  2. Ridimensiona il file restituito localmente alla dimensione esatta in pixel — una riga di Pillow.

Tabella di riferimento delle specifiche delle piattaforme e-commerce

Di seguito i requisiti pubblici comuni, mappati sui parametri dell'API:

Canale Target tipico aspect_ratio resolution Note sul modello
Immagine principale Amazon Lato lungo ≥1000 pixel (oltre 1600 pixel abilita lo zoom), quadrata, sfondo bianco puro 1:1 2K Entrambi vanno bene
Pagina prodotto Shopify Consigliato 2048×2048 1:1 2K Entrambi vanno bene
Feed Instagram (formato verticale) 1080×1350 4:5 2K Solo gpt-image-2
Stories / Reels / TikTok 1080×1920 9:16 2K Entrambi vanno bene
Pin Pinterest 1000×1500 2:3 2K Solo gpt-image-2
Listato Etsy Consigliato 2700×2025 4:3 4K Entrambi vanno bene (richiede il livello 4K)
Banner principale del sito Ad es. larghezza 2560 pixel 21:9 4K Entrambi vanno bene
Banner promozionale stretto Extra-wide 8:1 2K/4K Solo wan2.7-image

(Le specifiche delle piattaforme cambiano; considera questi target in pixel come consigli pubblici comuni e verifica con la documentazione aggiornata di ciascuna piattaforma.)

Esempio minimo funzionante (curl)

Tutto passa attraverso l'endpoint unificato per attività asincrone: crea con POST /v1/tasks, interroga con GET /v1/tasks/<id>. Crea un'immagine quadrata in stile Amazon, usando il livello 2K:

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"
    }
  }'

L'id dell'attività nella risposta si trova in data.taskId. Interrogalo:

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

Interroga finché data.status non diventa "success" (oppure "fail", con i dettagli sotto data.error). L'URL dell'immagine si trova in data.output[0].url. Quell'URL scade (l'oggetto output contiene expireAt), quindi scarica immediatamente e ri-ospita sul tuo storage — non fare mai hotlink diretto nei listati dei prodotti.

Script di produzione: un prodotto, tutti i canali, pixel esatti

Questo script batch crea in anticipo tutte le attività (vengono eseguite in parallelo sulla piattaforma), le interroga una per una fino al completamento, poi le ridimensiona con Pillow alle dimensioni target esatte. ImageOps.fit gestisce in una sola chiamata sia la riduzione sia qualsiasi ritaglio minore.

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",
}

# Canale -> parametri di generazione + target pixel esatto
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:
    # L'URL di output scade — scarica subito, poi adatta ai pixel esatti.
    raw = requests.get(url, timeout=120).content
    img = Image.open(BytesIO(raw))
    ImageOps.fit(img, px, Image.LANCZOS).save(path)


if __name__ == "__main__":
    # Crea prima tutte le attività: vengono eseguite in parallelo sulla piattaforma
    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")

Anche se riscrivi il resto, ci sono due dettagli che vale la pena copiare:

  • Scegli il livello di risoluzione in modo che il lato lungo sia ≥ al target. Il target di 2700 pixel di Etsy supera i circa 2048 pixel del livello 2K, quindi genera con 4K e poi riduci. La riduzione con LANCZOS è visivamente senza perdite per scopi di catalogo; l'ingrandimento no.
  • Persisti immediatamente taskId dopo aver creato l'attività. Se il tuo worker si blocca, al ripristino interroga l'id memorizzato invece di ricreare l'attività — ricrearla genererebbe (e fatturerebbe) una seconda immagine.

In alternativa, ricomponi un'immagine principale già approvata

Spesso non vuoi sette immagini generate indipendentemente — vuoi la stessa immagine di prodotto approvata, ricomposta per ogni canale. Ecco gpt-image-2/image-to-image: richiede input_urls (un array di URL di immagini accessibili pubblicamente) e prompt, e accetta gli stessi 16 valori di 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"
  }
}

Stesso ciclo di vita dell'attività, e alla fine lo stesso passaggio ai pixel esatti. Per la procedura completa vedi How to Use gpt-image-2 Image-to-Image via the hiapi API.

Note per la produzione

Usa i callback invece del polling. Per il lato server, passa un callback di primo livello alla creazione dell'attività e salta del tutto il ciclo di polling:

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

Riceverai un POST allo stato finale. Tratta il callback come segnale e non come fonte di verità: prima di agire, ri-recupera GET /v1/tasks/<id> e deduplica per taskId. Se il callback non arriva mai, vedi Why your hiapi task callback isn't firing.

Gestione degli errori. Un errore di autenticazione restituisce 401 permission_denied — controlla prima l'header Authorization: Bearer sk-.... Un errore di validazione restituisce 400 con error_code: "INVALID_REQUEST", e il messaggio è particolarmente utile: elenca i valori esattamente consentiti (è così che è stata verificata la tabella dei rapporti sopra). Lo schema di input varia da modello a modello — wan2.7-image accetta seed, gpt-image-2 no; alcuni modelli veloci rifiutano del tutto resolution — quindi controlla la pagina di ogni modello prima di codificare i campi.

Controllo dei costi. Il prezzo varia in base al modello e al livello di risoluzione. Genera con 1K mentre iteri sul prompt e passa a 2K/4K solo per le versioni finali — i prezzi correnti per immagine sono nella pagina dei prezzi.

Letture correlate

Domande frequenti

Posso passare dimensioni esatte in pixel come 1080×1350 nella richiesta? No. size, width e height vengono rifiutati con 400 (additional properties ... not allowed). Genera con un aspect_ratio corrispondente e un livello resolution uguale o superiore al target, poi riduci localmente ai pixel esatti — cioè la riga di Pillow sopra.

Quali impostazioni usare per l'immagine principale di Amazon? aspect_ratio: "1:1", resolution: "2K", poi ridimensiona al target (1600×1600 è un default affidabile — sopra la soglia di zoom di 1000 pixel). L'immagine principale di Amazon richiede anche uno sfondo bianco puro, quindi includilo nel prompt e rivedi l'output prima della pubblicazione.

Il mio rapporto target non è nell'elenco (ad esempio il formato annuncio link 1.91:1). Cosa faccio? Genera con il rapporto più vicino più largo o uguale che copra completamente il target — per 1.91:1 usa 2:1 o 16:9 — poi ritaglia al centro. ImageOps.fit nello script fa esattamente questo: in una sola chiamata ritaglia l'eccesso e ridimensiona.

Come ottengo vere immagini di prodotto in 4K? Imposta resolution: "4K" su entrambi i modelli. wan2.7-image è la scelta comune per immagini in stile studio 4K; per i modelli di prompt vedi la guida e-commerce Wan 2.7.

Gli URL delle immagini generate scadono? Sì — ogni output contiene expireAt. Scarica il file e ri-ospitalo sul tuo storage immediatamente dopo il successo dell'attività. Non incollare mai l'URL di output dell'attività nei listati dei prodotti.

Posso generare più varianti in una sola richiesta? No — questi modelli non hanno un parametro n. Crea un'attività per ogni immagine; le attività vengono eseguite in parallelo, quindi elaborarle in batch in un ciclo (come nello script sopra) è in pratica altrettanto veloce. Su wan2.7-image puoi variare seed per ottenere varianti controllate dello stesso prompt.

Inizia a creare con artefatti IA persistenti

Ottieni la tua chiave API e chiama modelli di immagini, video e audio tramite un'unica API basata sui task.

Leggi la documentazione API