HiAPI
Blog

Tutoriel

Comment utiliser l'API FLUX.1 Fill Pro : inpainting par masque avec curl et Python

Oct 24, 2026
Comment utiliser l'API FLUX.1 Fill Pro : inpainting par masque avec curl et Python

flux-1-fill-pro est le modèle d'inpainting basé sur un masque de hiapi : vous envoyez une image source, un masque en noir et blanc et une invite, et seules les zones blanches sont redessinées. Ce guide fournit des requêtes curl et Python prêtes à l'emploi, le flux asynchrone, ainsi que ce qu'une exécution réelle révèle sur les bords du masque et la taille de sortie. Vous devez obtenir une clé API depuis le dashboard.

Structure de la requête

Le modèle fonctionne sur l'API de tâches unifiée. Créez une tâche avec POST https://api.hiapi.ai/v1/tasks, interrogez GET /v1/tasks/<taskId>, puis lisez data.output[0].url. Les entrées suivantes proviennent de la page du modèle et de la documentation de l'API :

Champ Type Description
input.image URL, obligatoire Image source. JPEG, PNG, GIF ou WebP.
input.mask URL, obligatoire Le noir conserve l'image source, le blanc est redessiné. Doit avoir les mêmes dimensions que l'image source.
input.prompt string, obligatoire Décrit le nouveau contenu dans les zones blanches. Maximum 4 000 caractères.
input.steps int, 15–50 Par défaut 50.
input.guidance number, 1.5–100 Par défaut 60.
input.seed int Avec les mêmes entrées, un seed fixe produit des résultats cohérents.
input.output_format jpg | png Par défaut jpg.
input.prompt_upsampling bool Par défaut false. Laissez désactivé pour conserver votre formulation exacte.

image et mask sont tous deux des URL, pas du base64 ni des fichiers téléversés. Hébergez-les à un emplacement accessible en http(s) par l'API.

Requête curl minimale

curl -s https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-1-fill-pro",
    "input": {
      "image": "https://dev-static.hiapi.ai/model-onboarding/flux-1-fill-pro/2026/10/19/2026/10/19/1792418738578-4e5072a121d7018f-source.jpg",
      "mask": "https://dev-static.hiapi.ai/model-onboarding/flux-1-fill-pro/2026/10/19/2026/10/19/1792418739459-82bb18075f29c864-mask.png",
      "prompt": "Une grande peinture de paysage à l'huile représentant un lac de montagne brumeux dans la brume matinale, avec un fin cadre noir, accrochée bien à plat au mur ; gardez le canapé, le sol et l'éclairage inchangés.",
      "steps": 30,
      "guidance": 60,
      "seed": 42,
      "output_format": "png"
    }
  }'

La réponse est {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}. Interrogez cet ID jusqu'à ce que data.status soit success ou fail.

Python : créer, interroger, télécharger

import os, time, requests

API = "https://api.hiapi.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}

def inpaint(image_url, mask_url, prompt, **opts):
    body = {"model": "flux-1-fill-pro",
            "input": {"image": image_url, "mask": mask_url, "prompt": prompt, **opts}}
    r = requests.post(f"{API}/v1/tasks", headers=HEADERS, json=body, timeout=30)
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    while True:
        try:
            d = requests.get(f"{API}/v1/tasks/{task_id}", headers=HEADERS, timeout=20).json()["data"]
        except requests.RequestException:
            time.sleep(5)          # transient network error: poll the same taskId again
            continue
        if d["status"] == "success":
            return d["output"][0]["url"]
        if d["status"] == "fail":
            raise RuntimeError(d.get("error", d))
        time.sleep(5)

url = inpaint(
    "https://example.com/room.jpg",
    "https://example.com/room-mask.png",
    "Une peinture de paysage encadrée, fin cadre noir ; gardez la pièce inchangée.",
    steps=30, seed=42, output_format="png",
)
open("out.png", "wb").write(requests.get(url, timeout=60).content)

Téléchargez le résultat immédiatement. L'URL de sortie comporte un expireAt, et les fichiers sont stockés temporairement : ne conservez donc pas ce lien comme adresse permanente.

Points d'attention pour la production

  • Interrogation ou callback. Pour les tâches par lots, ajoutez "callback": {"url": "https://your-domain.com/hiapi/callback", "when": "final"} au body de la tâche, et dédupliquez les notifications à l'aide de l'ID de tâche. Conservez l'interrogation comme solution de repli.
  • Réessayez l'interrogation, pas la création. Un nouveau POST crée et facture une nouvelle tâche. Si une requête d'interrogation échoue, interrogez à nouveau le même taskId.
  • Gardez le masque cohérent avec l'image source. Le masque doit avoir exactement les mêmes dimensions que l'image source : générez-le donc à partir du même fichier (outil polygone, sortie de segmentation) plutôt qu'à partir d'une capture d'écran redimensionnée.
  • Figez le seed pendant le réglage. Utilisez le même seed et ne modifiez que steps ou guidance, afin que chaque différence provienne de ce paramètre.

Le coût par image figure sur la page de tarification ; vérifiez-le avant de lancer un grand volume d'images.

Ce qu'une exécution réelle a révélé

J'ai exécuté une fois la requête curl ci-dessus sur la photo de pièce d'exemple fournie avec cette page (1600×900) et son masque rectangulaire (cadre blanc situé à x 840–1240, y 160–580). Réglages : steps: 30, guidance: 60, seed: 42, output_format: png.

  • Durée. La tâche est restée en handling environ 25 secondes, puis en archiving, atteignant success en environ 38 secondes de bout en bout.
  • La taille de sortie diffère de l'image source. Le PNG renvoyé fait 1440×810, et non 1600×900. Le rapport hauteur/largeur est identique, mais les dimensions en pixels diffèrent. Si vous voulez recomposer le résultat sur l'image d'origine, redimensionnez d'abord l'une des deux ; ne supposez pas une correspondance 1:1.
  • Hors du masque, rien ne change. Après avoir redimensionné l'image source en 1440×810 et l'avoir comparée à la sortie, 81 % des pixels à l'intérieur du cadre blanc varient de plus de 8 niveaux (0–255), contre seulement 0,03 % des pixels à l'extérieur. À plus de 12 px du bord du masque, la différence maximale est de 11 niveaux. Le canapé, les coussins, la plante, le sol et la lumière de la fenêtre n'ont pas été redessinés.
  • Portée de l'invite. L'invite ne décrivait que le tableau et ce qu'il fallait conserver ; le résultat est une scène de lac de montagne encadrée remplissant le cadre blanc.
  • Une URL erronée échoue lors de l'interrogation, pas lors de la création. Une autre requête, avec image et mask définis sur des chaînes non-URL, a renvoyé 200 et un taskId, puis la tâche s'est terminée au bout d'environ 3 secondes avec status: fail et error.code: TASK_FAILED. Le succès de votre POST ne signifie pas que les entrées sont valides : vérifiez donc toujours l'état final.

Non testé : un masque dont les dimensions ne correspondent pas à l'image source, des masques avec des valeurs de gris (bords doux), des masques avec canal alpha, ainsi que des valeurs extrêmes de guidance ou steps. La documentation indique que le masque doit correspondre aux dimensions de l'image source, et je n'ai testé qu'un rectangle binaire net. Je n'ai pas exécuté plusieurs seeds ; je ne peux donc pas dire à quel point le remplissage varie d'une exécution à l'autre.

Quand choisir Fill Pro

Utilisez-le lorsque l'édition doit s'arrêter à une limite stricte que vous contrôlez, par exemple une étiquette de produit, une ligne de mur ou une couture de vêtement. Pour les éditions décrites en texte, sans masque, utilisez un modèle à invite seule. Le guide sur l'inpainting d'image et la suppression d'objets les compare. Pour effacer quelque chose d'un masque sans écrire d'invite, consultez le guide Bria Eraser.

Voir aussi

FAQ

image et mask sont-ils tous deux obligatoires ?

Oui. La documentation actuelle liste image, mask et prompt comme obligatoires.

Quelle couleur le modèle redessine-t-il ?

Le blanc. Les pixels noirs conservent l'image source.

Le masque doit-il avoir les mêmes dimensions que l'image source ?

C'est ce qu'indique la documentation. J'ai utilisé une paire correspondante dans mon exécution et je n'ai pas testé de cas de non-correspondance.

Quelles sont les dimensions de la sortie ?

Dans mon exécution, une image source de 1600×900 a renvoyé un PNG de 1440×810, avec le même rapport hauteur/largeur.

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