HiAPI
Blog

Tutoriel

Comment augmenter la résolution d'image avec l'API hiapi : un workflow d'agrandissement 4K

Une solution image-vers-image exécutable pour la génération à l'échelle 2K/4K, avec Python, callbacks et gestion des erreurs.

Sep 8, 2026
Comment augmenter la résolution d'image avec l'API hiapi : un workflow d'agrandissement 4K

Si vous disposez d'une photo produit en basse résolution, d'une petite vignette générée par IA ou d'un ancien scan dont vous avez besoin en version nette 2K/4K, vous n'avez pas besoin d'un service dédié à la super-résolution. L'endpoint unifié /v1/tasks de hiapi vous permet d'envoyer la même requête à plusieurs modèles d'image — des modèles qui acceptent une image existante et la redessinent à un palier de résolution supérieur. Cette solution présente le flux complet et exécutable : soumettre une tâche, interroger (ou recevoir un callback) pour obtenir le résultat, puis télécharger le fichier agrandi.

Une mise au point honnête d'abord : hiapi ne propose pas (encore) de modèle dédié à la super-résolution préservant les pixels. Ce que vous obtenez ici, c'est un agrandissement génératif — le modèle redessine votre image source à une résolution cible supérieure, tout en suivant un prompt qui lui demande de conserver la composition et d'ajouter des détails. Pour les photos et les illustrations, c'est généralement ce que les gens appellent « augmenter la résolution d'une image », mais ce n'est pas une interpolation sans perte : si vous avez besoin d'un redimensionnement pixel-exact d'une capture d'écran contenant de petits caractères, par exemple, n'utilisez pas cette approche.

Ce que vous allez construire et ce qu'il faut préparer

Vous allez construire un petit script qui va :

  1. Téléverser une référence vers une image que vous possédez déjà (n'importe quelle URL publique — votre propre CDN, R2, S3, etc.)
  2. Soumettre une tâche image-vers-image demandant un redessin en 4K
  3. Interroger jusqu'à ce que la tâche soit terminée, puis télécharger le résultat en plus haute résolution

Avant de commencer :

  • Un compte hiapi et une clé API, à créer sur la page API Keys du tableau de bord. Chaque requête ci-dessous exige Authorization: Bearer sk-<your-key> — sans clé, impossible d'appeler ces endpoints.
  • Une URL publiquement accessible pointant vers l'image à agrandir. Les workers de tâches hiapi récupèrent l'image côté serveur, donc un chemin localhost ou un bucket privé ne fonctionnera pas — téléversez d'abord l'image sur n'importe quel hôte public.
  • Python 3.8+ avec requests installé (pip install requests), ou directement curl si vous préférez tester dans le shell.

Exemple minimal exécutable

Le choix le plus propre est seedream-5.0-lite/image-to-image. Son schéma d'entrée exige exactement quatre champs — prompt, image_urls, aspect_ratio et resolution — et resolution n'accepte que 2K ou 4K (cette route n'a pas de palier 1K, ce qui signifie précisément que vous ne risquez pas de lui faire réduire votre image par accident).

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)

Si vous voulez juste voir à quoi ressemble la requête, voici l'appel équivalent de création de tâche avec 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"
    }
  }'

Quelques points méritent d'être signalés à propos de cette requête :

  • image_urls est un tableau, même si ce modèle ne lit que le premier élément. Passer une chaîne nue au lieu d'une liste est une cause fréquente d'erreur 400.
  • Les URL de sortie expirent. Dès que wait_for_result() retourne, téléchargez immédiatement les octets et stockez-les vous-même — ne considérez pas le lien hébergé par hiapi comme l'URL permanente de votre ressource.
  • Si votre image source n'est pas carrée, réglez aspect_ratio pour qu'il corresponde (4:3, 16:9, 9:16, 3:2, 2:3 ou 21:9), afin que le modèle ne recadre ni ne remplisse votre sujet.

En production

Privilégiez les callbacks au polling à l'échelle. Si vous avez plus de quelques images à agrandir, n'inondez pas GET /v1/tasks/<id> en boucle pour chaque tâche — passez un objet callback et laissez hiapi vous pousser les résultats :

payload = {
    "model": "seedream-5.0-lite/image-to-image",
    "input": {...},
    "callback": {
        "url": "https://your-service.example.com/hooks/hiapi-task",
        "when": "final",
    },
}

Votre webhook recevra le même objet de tâche que le polling (status, output, error) — validez sa structure de manière défensive, car les tentatives réseau peuvent le livrer plus d'une fois.

Préparez de votre côté une clé d'idempotence par tâche. L'API de tâches n'accepte pas encore de clé d'idempotence fournie par le client, donc si votre exécuteur de tâches risque de réessayer des appels HTTP échoués, vérifiez si un taskId a déjà été stocké pour cette image source avant de soumettre une tâche en double — sinon, un bref timeout de votre côté peut se transformer en un agrandissement facturé deux fois pour le même fichier.

Gérez deux formes d'erreur bien distinctes. Un corps de requête mal formé renvoie un HTTP 400 avec un {"code": 400, "error_code": "INVALID_REQUEST", "message": "..."} plat. Une clé API absente ou erronée renvoie un HTTP 401 avec un {"error": {"code": "permission_denied", "message": "..."}} imbriqué. Vérifiez d'abord le code de statut, puis branchez :

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()

Choisissez le modèle selon les entrées dont vous disposez. Les trois routes ci-dessous utilisent le même endpoint /v1/tasks — seuls la chaîne model et les champs input diffèrent :

Ce que vous avez Modèle Champs d'entrée requis
Une image existante, pour un redessin propre en 2K/4K seedream-5.0-lite/image-to-image prompt, image_urls, aspect_ratio, resolution (2K|4K)
Une image existante, avec un compromis entre qualité et coût gpt-image-2/image-to-image@ext prompt, image_urls, quality (low|medium|high), resolution (1K|2K|4K)
Aucune image source — générer une ressource haute résolution entièrement nouvelle à partir d'une description textuelle wan2.7-image/text-to-image prompt (plus éventuellement resolution et aspect_ratio)

Remarquez le suffixe @ext sur la deuxième ligne — c'est une variante de route du modèle de base gpt-image-2 (hiapi expose certains modèles sous plusieurs routes avec des paliers de tarification/qualité légèrement différents), et non une famille de modèles distincte. Le coût exact par requête de chacun dépend de la résolution et du palier de qualité choisis, donc consultez les chiffres actuels sur la page de tarification plutôt que de coder en dur des valeurs dans votre logique budgétaire.

Validez avant de soumettre. Ces trois modèles rejettent directement les champs d'entrée inconnus (additional properties 'x' not allowed) au lieu de les ignorer silencieusement, et les champs d'énumération comme resolution et aspect_ratio sont sensibles à la casse et aux valeurs. Si vous construisez une couche d'encapsulation, validez côté client selon les valeurs d'énumération exactes ci-dessus, afin qu'une faute de frappe échoue rapidement au lieu de consommer une requête pour rien.

Lectures associées

FAQ

hiapi propose-t-il un modèle dédié d'agrandissement d'image ou de super-résolution ? Aucun modèle dédié préservant les pixels. Le workflow ci-dessus utilise des modèles génériques image-vers-image qui régénèrent votre image à un palier de résolution supérieur ; cela fonctionne bien pour les photos et les illustrations, mais ce n'est pas un agrandissement sans perte.

Puis-je augmenter la résolution sans changer le contenu de l'image ? Vous pouvez vous en approcher de très près en demandant au modèle de conserver exactement la composition, les couleurs et le sujet (« même image, ne changez pas la composition, n'ajoutez ni ne supprimez d'éléments, ajoutez seulement du détail et de la netteté »), mais comme il s'agit d'un redessin génératif et non d'une interpolation, de subtiles différences subsisteront sur les textures fines par rapport à un véritable agrandisseur sans perte.

Quelle est la résolution maximale que je peux générer ? Les trois modèles ci-dessus plafonnent au palier de résolution 4K. Si vous avez besoin de dimensions supérieures, vous devrez découper l'image source en blocs et agrandir chaque bloc séparément, ou ajouter une étape de redimensionnement côté client après l'appel API.

Faut-il une clé API pour essayer ? Oui — chaque appel /v1/tasks exige Authorization: Bearer sk-<your-key>. Il n'existe pas de bac à sable sans clé pour créer des tâches ; commencez par obtenir une clé depuis le tableau de bord.

Puis-je agrandir en lot tout un dossier d'images ? Oui — parcourez vos URL d'images, soumettez une tâche par image, puis soit interrogez chaque taskId, soit (mieux pour de gros volumes) enregistrez une URL de callback et faites correspondre les résultats à vos tâches grâce au taskId stocké lors de la création de chaque tâche.

Pourquoi ma requête échoue-t-elle avec « additional properties not allowed » ? Vous avez envoyé un champ que le schéma du modèle ne connaît pas — par exemple size au lieu de resolution + aspect_ratio, ou un paramètre superflu copié depuis l'exemple d'un autre modèle. Consultez le tableau des champs requis ci-dessus pour connaître les noms exacts acceptés par chaque modèle.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API