Une image, plusieurs images, comparer
Une fonction pour tous les fichiers
Plutôt que de répéter Part.from_bytes(...) partout, le lab centralise la préparation dans part_from(). Elle devine le type MIME d'après l'extension et choisit inline ou API Files.
INLINE_MAX = 20 * 1024 * 1024
MIME = {".png": "image/png", ".jpg": "image/jpeg", ".pdf": "application/pdf",
".wav": "audio/wav", ".mp4": "video/mp4", ...}
def mime_of(path) -> str:
p = Path(path)
return MIME.get(p.suffix.lower()) or mimetypes.guess_type(p.name)[0] or "application/octet-stream"
def doit_uploader(path, forcer_files=False) -> bool:
return forcer_files or mime_of(path).startswith("video/") or Path(path).stat().st_size > INLINE_MAX
def part_from(client, path, forcer_files=False):
if doit_uploader(path, forcer_files):
return uploader(client, path) # API Files, voir leçon suivante
return types.Part.from_bytes(data=Path(path).read_bytes(), mime_type=mime_of(path))Code complet : multimodal.py.
Formats d'image acceptés par Gemini : PNG, JPEG, WEBP, HEIC et HEIF.
Plusieurs images : étiquetez-les
Une requête peut contenir de nombreuses images (la documentation annonce jusqu'à 3 600). Le piège : sans repère, le modèle et vous ne parlerez pas de la même image. La solution est simple : placez un texte « Image 1 : » juste avant chaque image.
def comparer_images(client, chemins):
parts = []
for i, c in enumerate(chemins, 1):
parts += [f"Image {i} :", part_from(client, c)]
parts.append("Compare ces justificatifs : type, émetteur, date, total. "
"Lequel est une facture d'entreprise ? Réponds en 5 lignes maximum.")
r = generer(client, parts)
return {"texte": r.text, "tokens": tokens(r)}sequenceDiagram participant P as "Votre programme" participant G as "Gemini" P->>G: "Image 1 :" + ticket.png + "Image 2 :" + facture.png + consigne G-->>P: "Image 2 est la facture (SIRET, HT/TVA, échéance)"
| Cas d'usage | Ce qu'on envoie | Question type |
|---|---|---|
| Détection de doublon | deux photos de tickets | « Est-ce le même achat ? » |
| Contrôle qualité | photo de référence + photo du produit | « Quelles différences visibles ? » |
| Avant / après | deux photos d'un chantier | « Qu'est-ce qui a été fait ? » |
| Tri | dix justificatifs | « Classe-les par type et par date » |
Pourquoi ajouter le texte « Image 1 : » avant chaque image ?
L'API accepte des images sans étiquette, mais la réponse dirait « la première » ou « celle de gauche », ce qui devient ambigu au-delà de deux. L'étiquette ajoute quelques tokens, elle ne les réduit pas.
Votre comparaison de deux photos coûte environ 2 200 tokens d'entrée. Combien environ pour dix photos similaires ?
Chaque image est convertie en tokens indépendamment, environ 1 100 ici. Dix images font donc à peu près cinq fois plus que deux. Pensez-y avant d'envoyer des lots de photos haute résolution.
Exercice : détecter un doublon
Copiez ticket.png en ticket2.png, puis écrivez l'appel qui demande si les deux images sont le même achat. Que doit-on vérifier en plus, sans IA, avant de rejeter une note de frais pour doublon ?
Voir la solution
res = comparer_images(client, ["ticket.png", "ticket2.png"])
# ou, avec une consigne dédiée :
parts = ["Image 1 :", part_from(client, "ticket.png"), "Image 2 :", part_from(client, "ticket2.png"),
"Ces deux justificatifs correspondent-ils au même achat ? Réponds OUI ou NON puis justifie "
"avec le commerçant, la date, l'heure, le numéro de ticket et le total."]Avant de rejeter : comparer en Python les champs extraits (numéro de ticket, date, heure, total) après une extraction JSON (module 4). Le modèle peut se tromper ; une décision qui pénalise quelqu'un passe par une règle vérifiable et une validation humaine.
Résultat obtenu
python multimodal.py comparer ticket.png facture.png, exécution réelle du 2026-10-15 :
* Image 1 : Ticket de caisse émis par la Boulangerie du Canal le 14/10/2026 pour un total TTC de 9,50 €.
* Image 2 : Facture émise par la Papeterie Martin & Fils le 02/10/2026 pour un total TTC de 87,60 € (73,00 € HT).
La facture d'entreprise est l'Image 2 : elle mentionne un client professionnel (Atelier Nord),
un numéro SIRET, le détail HT/TVA et une date d'échéance de paiement par virement.
"tokens": {"entree": 2207, "sortie": 164}- Je sais préparer un fichier avec
part_from()et son type MIME - Je sais envoyer plusieurs images étiquetées dans une seule requête
- Je sais estimer le coût d'un lot d'images à partir d'une mesure