Tutoriale
Come aumentare la risoluzione delle immagini con l'API di hiapi: un flusso di lavoro per l'upscaling 4K
Una soluzione image-to-image eseguibile per l'upscaling generativo 2K/4K, con Python, callback e gestione degli errori.
Se hai un'immagine prodotto a bassa risoluzione, una piccola miniatura generata dall'AI o una vecchia scansione e ti serve una versione nitida in 2K/4K, non hai bisogno di un servizio dedicato alla super-risoluzione. L'endpoint unificato /v1/tasks di hiapi ti permette di inviare la stessa richiesta a diversi modelli di immagine — modelli che accettano un'immagine esistente e la ridisegnano a una risoluzione superiore. Questa soluzione mostra il flusso di lavoro completo ed eseguibile: inviare il task, fare polling (o ricevere un callback) per il risultato, quindi scaricare il file ingrandito.
Una precisazione onesta: al momento hiapi non espone (ancora) un modello dedicato di super-risoluzione che preservi i pixel. Quello che ottieni qui è un upscaling generativo — il modello ridisegna la tua immagine sorgente alla risoluzione obiettivo più alta, seguendo un prompt che gli chiede di preservare la composizione e aggiungere dettaglio. Per foto e illustrazioni è spesso quello che la gente intende con "aumentare la risoluzione di un'immagine", ma non è un'interpolazione lossless, quindi se ti serve un ridimensionamento pixel-perfect di, ad esempio, uno screenshot con testo piccolo, non usare questo approccio.
Cosa costruirai e cosa preparare prima
Costruirai un piccolo script che:
- carica un riferimento alla tua immagine esistente (qualsiasi URL pubblico va bene — il tuo CDN, R2, S3, ecc.)
- invia un task image-to-image che richiede un ridisegno in 4K
- fa polling finché il task non è completato e scarica il risultato a risoluzione più alta
Prima di iniziare:
- Un account hiapi e una chiave API, da creare nella pagina API Keys della dashboard. Ogni richiesta qui sotto richiede
Authorization: Bearer sk-<your-key>— senza chiave non puoi chiamare questi endpoint. - Un URL pubblicamente accessibile che punta all'immagine che vuoi ingrandire. I worker dei task di hiapi recuperano l'immagine lato server, quindi percorsi
localhosto bucket privati non funzionano — carica prima su un host pubblico qualsiasi. - Python 3.8+ con
requestsinstallato (pip install requests), oppure usa direttamentecurlse preferisci testare dalla shell.
Esempio minimo eseguibile
L'opzione più pulita è seedream-5.0-lite/image-to-image. Il suo schema di input richiede esattamente quattro campi — prompt, image_urls, aspect_ratio e resolution — e resolution accetta solo 2K o 4K (su questa route non esiste il livello 1K, il che significa che non puoi accidentalmente fargli ridurre l'immagine).
import time
import requests
API_KEY = "sk-your-hiapi-key" # from https://www.hiapi.ai/en/dashboard/api-keys
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_upscale_task(source_image_url: str) -> str:
payload = {
"model": "seedream-5.0-lite/image-to-image",
"input": {
"prompt": "Same image, preserved composition and colors, sharp fine detail, no artifacts",
"image_urls": [source_image_url],
"aspect_ratio": "1:1", # match your source image's ratio
"resolution": "4K",
},
}
resp = requests.post(BASE, headers=HEADERS, json=payload, timeout=60)
resp.raise_for_status()
body = resp.json()
task_id = body["data"]["taskId"]
return task_id
def wait_for_result(task_id: str, timeout_s: int = 300, poll_every: int = 5) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
resp = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
task = resp.json()["data"]
if task["status"] == "success":
return task["output"][0]["url"]
if task["status"] == "fail":
err = task.get("error", {})
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(poll_every)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = create_upscale_task("https://your-cdn.example.com/product-photo-small.jpg")
result_url = wait_for_result(task_id)
print("4K result:", result_url)
Se vuoi solo vedere com'è fatta la richiesta, ecco la chiamata equivalente per creare il task con curl:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-your-hiapi-key" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5.0-lite/image-to-image",
"input": {
"prompt": "Same image, preserved composition and colors, sharp fine detail, no artifacts",
"image_urls": ["https://your-cdn.example.com/product-photo-small.jpg"],
"aspect_ratio": "1:1",
"resolution": "4K"
}
}'
Vale la pena segnalare alcune cose su questa richiesta:
image_urlsè un array, anche se questo modello legge solo il primo elemento. Passare una stringa nuda invece di una lista è una causa frequente di errore 400.- Gli URL di output scadono. Appena
wait_for_result()restituisce, scarica subito i byte e archiviali per conto tuo — non usare il link ospitato da hiapi come URL permanente della tua risorsa. - Se la tua immagine sorgente non è quadrata, imposta
aspect_ratioin modo che corrisponda (4:3,16:9,9:16,3:2,2:3o21:9), così il modello non ritaglia né riempie il tuo soggetto.
Come fare in produzione
Su larga scala, preferisci i callback al polling. Se devi ingrandire più di poche immagini, non martellare GET /v1/tasks/<id> in un loop per ogni task — passa un oggetto callback e lascia che hiapi ti invii il risultato:
payload = {
"model": "seedream-5.0-lite/image-to-image",
"input": {...},
"callback": {
"url": "https://your-service.example.com/hooks/hiapi-task",
"when": "final",
},
}
Il tuo webhook riceverà lo stesso oggetto task del polling (status, output, error) — validane la struttura in modo difensivo, perché i retry di rete potrebbero consegnarlo più di una volta.
Prepara dalla tua parte una chiave idempotente per ogni task. L'API dei task al momento non accetta chiavi di idempotenza fornite dal client, quindi se il tuo task runner può ritentare chiamate HTTP fallite, controlla se hai già salvato un taskId per quella immagine sorgente prima di inviare un task duplicato — altrimenti un breve timeout dalla tua parte può trasformarsi in un doppio addebito per l'upscaling dello stesso file.
Gestisci due forme di errore molto diverse. Un corpo della richiesta malformato restituisce HTTP 400 con un oggetto piatto {"code": 400, "error_code": "INVALID_REQUEST", "message": "..."}. Una chiave API mancante o errata restituisce HTTP 401 con un oggetto annidato {"error": {"code": "permission_denied", "message": "..."}}. Controlla prima il codice di stato, poi ramifica:
if resp.status_code == 401:
raise RuntimeError(f"auth error: {resp.json()['error']['message']}")
if resp.status_code == 400:
raise RuntimeError(f"bad request: {resp.json()['message']}")
resp.raise_for_status()
Scegli il modello in base a cosa hai come input. Le tre route qui sotto usano tutte lo stesso endpoint /v1/tasks — cambiano solo la stringa model e i campi di input:
| Cosa hai | Modello | Campi di input obbligatori |
|---|---|---|
| Un'immagine esistente, e vuoi un ridisegno pulito in 2K/4K | seedream-5.0-lite/image-to-image |
prompt, image_urls, aspect_ratio, resolution (2K|4K) |
| Un'immagine esistente, e vuoi bilanciare qualità e costo | gpt-image-2/image-to-image@ext |
prompt, image_urls, quality (low|medium|high), resolution (1K|2K|4K) |
| Nessuna immagine sorgente — genera una risorsa ad alta risoluzione da zero partendo da una descrizione testuale | wan2.7-image/text-to-image |
prompt (più resolution e aspect_ratio opzionali) |
Nota il suffisso @ext sulla seconda riga — è una variante di route sul modello base gpt-image-2 (hiapi espone alcuni modelli sotto più di una route, con prezzi/livelli di qualità leggermente diversi), non una famiglia di modelli separata. Il costo esatto per richiesta di ciascuno dipende dal livello di risoluzione e qualità che scegli, quindi controlla le cifre attuali sulla pagina dei prezzi invece di codificare valori fissi nella tua logica di budget.
Valida prima di inviare. Tutti e tre i modelli rifiutano direttamente i campi di input sconosciuti (additional properties 'x' not allowed) invece di ignorarli silenziosamente, e i campi enum come resolution e aspect_ratio distinguono maiuscole/minuscole e sono sensibili ai valori. Se stai costruendo un wrapper, valida lato client con i valori enum esatti indicati sopra, così un refuso fallisce subito invece di sprecare una richiesta.
Letture correlate
- Wan 2.7 Image — API text-to-image, per generare da zero immagini ad alta risoluzione partendo solo da un prompt.
- GPT Image 2 API, l'alternativa con livelli di qualità/risoluzione usata nella tabella sopra.
- Prezzi dell'API hiapi, per vedere il costo attuale per richiesta di ogni modello e livello.
- Documentazione di hiapi, per il riferimento completo sul ciclo di vita dei task, incluse tutte le opzioni di callback.
Domande frequenti
hiapi ha un modello dedicato per l'ingrandimento o la super-risoluzione delle immagini? Non esiste un modello dedicato che preservi i pixel. Il flusso di lavoro sopra usa modelli generici di image-to-image per rigenerare la tua immagine a una risoluzione superiore, il che funziona bene per foto e illustrazioni, ma non è un ingrandimento lossless.
Posso aumentare la risoluzione senza cambiare il contenuto dell'immagine? Puoi avvicinarti molto chiedendo al modello di preservare esattamente composizione, colori e soggetto ("stessa immagine, non cambiare la composizione, non aggiungere né rimuovere elementi, aumenta solo dettaglio e nitidezza"), ma poiché si tratta di un ridisegno generativo e non di un'interpolazione, sulle texture fini resteranno comunque piccole differenze rispetto a un vero ingranditore lossless.
Qual è la risoluzione massima che posso generare?
Tutti e tre i modelli sopra hanno un limite di 4K come livello di risoluzione. Se ti serve una dimensione maggiore, devi dividere l'immagine sorgente in blocchi e ingrandire ciascun blocco, oppure aggiungere un passaggio di ridimensionamento lato client dopo la chiamata API.
Serve una chiave API per provare questo?
Sì — ogni chiamata a /v1/tasks richiede Authorization: Bearer sk-<your-key>. Non c'è una sandbox senza chiave per creare task; ottieni prima una chiave dalla dashboard.
Posso ingrandire in batch un'intera cartella di immagini?
Sì — itera sui tuoi URL delle immagini, invia un task per ciascuna immagine, poi o fai polling su ogni taskId, oppure (meglio quando i volumi sono alti) registra un URL di callback e usa il taskId salvato al momento della creazione di ogni task per associare i risultati ai tuoi task.
Perché la mia richiesta fallisce con "additional properties not allowed"?
Hai inviato un campo che lo schema del modello non riconosce — ad esempio usando size invece di resolution + aspect_ratio, oppure copiando un parametro di troppo dagli esempi di un altro modello. Controlla la tabella dei campi obbligatori sopra per i nomi esatti dei campi accettati da ciascun modello.
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