Variations et itérations
Variations et itérations
Obtenir l’image parfaite du premier coup est rare. Cette leçon vous apprend à générer des variations systématiques et à itérer méthodiquement sur vos résultats pour converger vers le rendu souhaité.
Générer des variations d’un même concept
La méthode la plus simple consiste à relancer la génération avec le même prompt. GPT Image produit un résultat différent à chaque appel :
from openai import OpenAI
import base64
client = OpenAI()
def generer_variations(prompt: str, n_variations: int, prefix: str):
"""Génère plusieurs variations indépendantes d'un même prompt."""
paths = []
for i in range(n_variations):
response = client.images.generate(
model="gpt-image-1",
prompt=prompt,
size="1024x1024",
quality="medium",
response_format="b64_json"
)
path = f"{prefix}_v{i+1}.png"
data = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(data)
paths.append(path)
print(f"Variation {i+1} sauvegardée : {path}")
return paths
variations = generer_variations(
prompt="Illustration d'un robot jardinier arrosant des fleurs, style enfantin et coloré",
n_variations=5,
prefix="robot_jardinier"
)
Variations par modification du prompt
Une approche plus contrôlée consiste à modifier systématiquement un aspect du prompt :
from openai import OpenAI
import base64
client = OpenAI()
base_prompt = "Tasse de café fumante sur une table en bois"
ambiances = [
"lumière matinale douce, tons chauds",
"ambiance café parisien, noir et blanc",
"style pop art, couleurs saturées",
"minimaliste scandinave, fond blanc",
"atmosphère cosy d'hiver, bokeh de guirlandes",
]
for i, ambiance in enumerate(ambiances):
prompt = f"{base_prompt}, {ambiance}"
response = client.images.generate(
model="gpt-image-1",
prompt=prompt,
size="1024x1024",
quality="medium",
response_format="b64_json"
)
path = f"cafe_ambiance_{i+1}.png"
data = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(data)
print(f"Ambiance : {ambiance[:30]}... → {path}")
Itération par raffinement du prompt
Quand le résultat n’est pas satisfaisant, affinez le prompt étape par étape :
from openai import OpenAI
import base64
client = OpenAI()
iterations = [
# Itération 1 : prompt de base
"Un logo pour une startup fintech",
# Itération 2 : ajout de contraintes visuelles
"Un logo pour une startup fintech, design minimaliste, deux couleurs maximum, fond transparent",
# Itération 3 : précision du style
(
"Logo minimaliste pour une startup fintech, icône géométrique abstraite "
"évoquant la croissance, palette bleu marine et vert émeraude, sans texte, vectoriel"
),
# Itération 4 : ajustements fins
(
"Logo minimaliste pour une startup fintech, icône géométrique abstraite : "
"deux flèches entrelacées formant un losange, bleu marine (#1B2A4A) et "
"vert émeraude (#2ECC71), trait fin 2px, fond blanc, rendu vectoriel net, centré"
),
]
for i, prompt in enumerate(iterations):
response = client.images.generate(
model="gpt-image-1",
prompt=prompt,
size="1024x1024",
quality="high",
response_format="b64_json"
)
path = f"logo_iteration_{i+1}.png"
data = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(data)
print(f"Itération {i+1} : {prompt[:60]}...")
print(f" → {path}\n")
Pipeline d’itération automatisé
Créez un pipeline qui génère, évalue et affine automatiquement :
from openai import OpenAI
import base64
import json
client = OpenAI()
def pipeline_iteration(brief: str, n_rounds: int = 3, n_par_round: int = 3):
"""
Pipeline d'itération : génère plusieurs variantes par round,
garde un historique des prompts et résultats.
"""
historique = []
prompt_courant = brief
for round_num in range(1, n_rounds + 1):
print(f"\n{'='*50}")
print(f"ROUND {round_num} — Prompt : {prompt_courant[:80]}...")
print(f"{'='*50}")
images_round = []
for i in range(n_par_round):
response = client.images.generate(
model="gpt-image-1",
prompt=prompt_courant,
size="1024x1024",
quality="medium",
response_format="b64_json"
)
path = f"pipeline_r{round_num}_v{i+1}.png"
data = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(data)
images_round.append(path)
print(f" Variante {i+1} : {path}")
historique.append({
"round": round_num,
"prompt": prompt_courant,
"images": images_round
})
# Affiner le prompt pour le round suivant
if round_num < n_rounds:
prompt_courant += ", plus de détails, meilleure composition"
# Sauvegarder l'historique
with open("pipeline_historique.json", "w") as f:
json.dump(historique, f, indent=2, ensure_ascii=False)
print(f"\nHistorique sauvegardé : pipeline_historique.json")
return historique
pipeline_iteration(
brief="Illustration d'une librairie indépendante vue de l'extérieur, soir d'automne, style Ghibli",
n_rounds=3,
n_par_round=3
)
Comparer les variations avec un catalogue
Pour faciliter la comparaison, générez un catalogue HTML de toutes vos variations :
import base64
from pathlib import Path
from glob import glob
def generer_catalogue(images: list[str], titre: str, output: str = "catalogue.html"):
"""Crée une page HTML avec toutes les images côte à côte."""
html_parts = [
'<!DOCTYPE html><html><head><meta charset="utf-8">',
f'<title>{titre}</title>',
'<style>',
'body { background: #111; color: #fff; font-family: sans-serif; padding: 2rem; }',
'.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; }',
'.card { background: #222; border-radius: 8px; overflow: hidden; }',
'.card img { width: 100%; display: block; }',
'.card p { padding: 0.5rem 1rem; font-size: 0.85rem; color: #aaa; }',
'</style></head><body>',
f'<h1>{titre}</h1><div class="grid">',
]
for img_path in images:
with open(img_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode()
html_parts.append(f'<div class="card">')
html_parts.append(f'<img src="data:image/png;base64,{b64}" />')
html_parts.append(f'<p>{Path(img_path).name}</p></div>')
html_parts.append('</div></body></html>')
with open(output, "w") as f:
f.write("\n".join(html_parts))
print(f"Catalogue généré : {output}")
images = sorted(glob("pipeline_r*_v*.png"))
generer_catalogue(images, "Variations — Librairie Ghibli")
Bonnes pratiques d’itération
- Changez un seul paramètre à la fois pour identifier ce qui améliore le résultat
- Gardez un historique de vos prompts et résultats pour capitaliser
- Utilisez
quality: lowpendant les phases d’exploration,highuniquement pour le rendu final - Générez en batch (paramètre
n) plutôt qu’en boucle quand vous voulez de la diversité rapide - Nommez vos fichiers de manière descriptive pour retrouver facilement les bonnes variantes
Exercice pratique
Choisissez un sujet (logo, illustration, photo de produit). Créez un pipeline qui :
- Génère 3 variantes avec un prompt initial
- Affine le prompt et génère 3 nouvelles variantes
- Produit un catalogue HTML comparatif des 6 résultats