Tutoriale
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:
- 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).
- 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
4Ke poi riduci. La riduzione con LANCZOS è visivamente senza perdite per scopi di catalogo; l'ingrandimento no. - Persisti immediatamente
taskIddopo 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
- Pagina del modello gpt-image-2 text-to-image · Pagina del modello wan2.7-image text-to-image
- How to use gpt-image-2/text-to-image via the hiapi API — procedura completa dei parametri
- Wan 2.7 Text-to-Image for E-Commerce Product Photos: 4K Studio Shots
- Best AI Image Generation APIs in 2026 — se stai ancora scegliendo, vedi il confronto tra modelli
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.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato