HiAPI
Blog

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.

Sep 8, 2026
Come aumentare la risoluzione delle immagini con l'API di hiapi: un flusso di lavoro per l'upscaling 4K

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:

  1. carica un riferimento alla tua immagine esistente (qualsiasi URL pubblico va bene — il tuo CDN, R2, S3, ecc.)
  2. invia un task image-to-image che richiede un ridisegno in 4K
  3. 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 localhost o bucket privati non funzionano — carica prima su un host pubblico qualsiasi.
  • Python 3.8+ con requests installato (pip install requests), oppure usa direttamente curl se 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_ratio in modo che corrisponda (4:3, 16:9, 9:16, 3:2, 2:3 o 21: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

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.

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