Skip to content
Learni
Voir tous les tutoriels
Google Cloud

Comment intégrer la Google Cloud Vision API en 2026

Read in English

Introduction

La Google Cloud Vision API est un service d'IA puissant pour analyser des images : détection d'objets, reconnaissance optique de caractères (OCR), analyse de visages avec landmarks émotionnels, et bien plus. En 2026, elle intègre les dernières avancées en vision par ordinateur, comme la détection contextuelle et le SAFE_SEARCH pour la modération de contenu.

Pourquoi l'utiliser ? Pour des applications comme l'analyse automatisée de documents, la surveillance vidéo intelligente ou l'e-commerce avec tagging automatique d'images. Ce tutoriel advanced cible les développeurs seniors : nous couvrons l'authentification service account, les features complexes (landmarks faciaux, localisation d'objets), le batch processing pour scaler, et les optimisations coûts/performance. À la fin, vous déployez une API Node.js robuste. Comptez 2000+ mots de concret, zéro fluff. Préparez votre compte Google Cloud et une clé JSON.

Prérequis

  • Compte Google Cloud activé avec Vision API (facturation requise, ~1,50$/1000 images).
  • Node.js 20+ et TypeScript.
  • Clé de service account JSON (créez-en une via IAM > Service Accounts > Create Key > JSON).
  • Une image test locale (ex: test.jpg pour labels, document.png pour OCR).
  • Connaissances avancées en async/await, streams et gestion d'erreurs Node.js.

Installation du projet

terminal
mkdir vision-api-project && cd vision-api-project
npm init -y
npm install @google-cloud/vision typescript ts-node @types/node
npm install -D nodemon
tsc --init --target es2022 --module commonjs --outDir ./dist --rootDir ./src --strict true
echo '{
  "compilerOptions": {
    "target": "ES2022",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}' > tsconfig.json

Ce script initialise un projet TypeScript propre avec @google-cloud/vision. ts-node permet d'exécuter directement les .ts ; nodemon pour le dev. Placez votre service-account-key.json à la racine. Lancez avec npx ts-node src/index.ts.

Authentification et client init

Téléchargez votre clé JSON depuis Google Cloud Console (IAM > Service Accounts). Activez la Vision API dans APIs & Services. Ne commitez jamais cette clé : utilisez .env ou secrets manager en prod. Le client ImageAnnotatorClient gère les appels REST sous le capot, avec retry automatique.

Détection de labels basique

src/basic-labels.ts
import { ImageAnnotatorClient } from '@google-cloud/vision';
import * as fs from 'fs';
import * as path from 'path';

const keyPath = path.join(__dirname, '../service-account-key.json');
const client = new ImageAnnotatorClient({ keyFilename: keyPath });

const fileName = path.join(__dirname, '../test.jpg');

const request = {
  image: { content: fs.readFileSync(fileName).toString('base64') },
  features: [{ type: 'LABEL_DETECTION', maxResults: 10 }]
};

async function detectLabels() {
  try {
    const [result] = await client.annotateImage(request);
    const labels = result.labelAnnotations;
    console.log('Labels:', labels?.map(l => `${l.description} (${l.score})`).join('\n'));
  } catch (error) {
    console.error('Erreur:', error);
  }
}

detectLabels();

Ce script charge une image en base64, détecte 10 labels max avec scores de confiance. Analogie : comme un expert ornithologue identifiant oiseaux sur photo. Piège : oubliez toString('base64') et l'API rejette. Scores <0.8 souvent noisy.

OCR avancé multilingue

src/ocr-advanced.ts
import { ImageAnnotatorClient } from '@google-cloud/vision';
import * as fs from 'fs';
import * as path from 'path';

const keyPath = path.join(__dirname, '../service-account-key.json');
const client = new ImageAnnotatorClient({ keyFilename: keyPath });

const fileName = path.join(__dirname, '../document.png');

const request = {
  image: { content: fs.readFileSync(fileName).toString('base64') },
  features: [
    { type: 'TEXT_DETECTION', maxResults: 1 },
    { type: 'DOCUMENT_TEXT_DETECTION', maxResults: 1 }
  ],
  imageContext: {
    languageHints: ['fr', 'en', 'es']
  }
};

async function detectText() {
  try {
    const [result] = await client.annotateImage(request);
    const texts = result.textAnnotations;
    console.log('Texte principal:', texts?.[0]?.description);
    texts?.slice(1).forEach((text, i) => {
      console.log(`Bloc ${i + 1}:`, text.description);
    });
  } catch (error) {
    console.error('Erreur OCR:', error);
  }
}

detectText();

Utilise DOCUMENT_TEXT_DETECTION pour docs structurés (vs TEXT_DETECTION pour texte simple). languageHints booste précision multilingue. Analogie : scanner haute-res comme un archiviste. Piège : images floues → forcez pré-processing (sharpening).

Analyse de visages avec landmarks

Face detection avancée extrait émotions (joy, sorrow), landmarks (yeux, nez) pour tracking. Utile en AR/VR ou sécurité. Combine avec SAFE_SEARCH_DETECTION pour modération.

Détection visages et landmarks

src/face-landmarks.ts
import { ImageAnnotatorClient } from '@google-cloud/vision';
import * as fs from 'fs';
import * as path from 'path';

type Landmark = { type: string; position: { x: number; y: number } };

const keyPath = path.join(__dirname, '../service-account-key.json');
const client = new ImageAnnotatorClient({ keyFilename: keyPath });

const fileName = path.join(__dirname, '../portrait.jpg');

const request = {
  image: { content: fs.readFileSync(fileName).toString('base64') },
  features: [
    { type: 'FACE_DETECTION', maxResults: 5 },
    { type: 'SAFE_SEARCH_DETECTION' }
  ]
};

async function detectFaces() {
  try {
    const [result] = await client.annotateImage(request);
    const faces = result.faceAnnotations;
    const safe = result.safeSearchAnnotation;
    faces?.forEach((face, i) => {
      console.log(`Visage ${i + 1}:`);
      console.log('Joie:', face.joyLikelihood);
      console.log('Landmarks:', face.landmarkAnnotations?.slice(0, 5).map((l: Landmark) => `${l.type}: (${l.position?.x?.toFixed(0)}, ${l.position?.y?.toFixed(0)})`));
    });
    console.log('SafeSearch:', safe);
  } catch (error) {
    console.error('Erreur faces:', error);
  }
}

detectFaces();

Extrait joyLikelihood (VERY_LIKELY, etc.) et 5 premiers landmarks (RIGHT_EYE, etc.). SAFE_SEARCH score ADULT/VIOLENCE. Analogie : profiler facial comme un détective. Piège : boundingPoly ignoré → perd localisation ; utilisez pour crop.

Localisation d'objets

src/object-localization.ts
import { ImageAnnotatorClient } from '@google-cloud/vision';
import * as fs from 'fs';
import * as path from 'path';

const keyPath = path.join(__dirname, '../service-account-key.json');
const client = new ImageAnnotatorClient({ keyFilename: keyPath });

const fileName = path.join(__dirname, '../scene.jpg');

const request = {
  image: { content: fs.readFileSync(fileName).toString('base64') },
  features: [{ type: 'OBJECT_LOCALIZATION', maxResults: 10 }],
  imageContext: { pageSize: 2 }
};

async function localizeObjects() {
  try {
    const [result] = await client.annotateImage(request);
    const objects = result.localizedObjectAnnotations;
    objects?.forEach(obj => {
      console.log(`Objet: ${obj.name} (score: ${obj.score})`);
      const vertices = obj.boundingPoly?.normalizedVertices;
      console.log('BBox:', vertices?.map(v => `(${v.x?.toFixed(2)}, ${v.y?.toFixed(2)})`));
    });
  } catch (error) {
    console.error('Erreur objets:', error);
  }
}

localizeObjects();

OBJECT_LOCALIZATION donne bounding boxes normalisées (0-1). pageSize:2 pour pagination. Analogie : heatmap objets comme un radar. Piège : normalizedVertices pour scale-invariante ; dénormalisez avec largeur/hauteur image.

Batch processing multi-images

src/batch-analysis.ts
import { ImageAnnotatorClient } from '@google-cloud/vision';
import * as fs from 'fs';
import * as path from 'path';

const keyPath = path.join(__dirname, '../service-account-key.json');
const client = new ImageAnnotatorClient({ keyFilename: keyPath });

const images = ['test1.jpg', 'test2.jpg', 'test3.jpg'].map(name => path.join(__dirname, '../', name));

const requests = images.map(imagePath => ({
  image: { content: fs.readFileSync(imagePath).toString('base64') },
  features: [{ type: 'LABEL_DETECTION', maxResults: 5 }]
}));

async function batchAnnotate() {
  try {
    const [results] = await client.batchAnnotateImages({ requests });
    results.forEach((result, i) => {
      console.log(`Image ${i + 1}:`);
      const labels = result.labelAnnotations;
      console.log(labels?.map(l => l.description).join(', '));
    });
  } catch (error) {
    console.error('Erreur batch:', error);
  }
}

batchAnnotate();

batchAnnotateImages traite jusqu'à 16 images en parallèle, économise quotas/coûts. Analogie : convoyeur d'analyse IA. Piège : erreur sur une image n'arrête pas le batch, mais loggez error dans fullTextAnnotation.

Bonnes pratiques

  • Cachez résultats : labels/OCR stables → Redis avec TTL 24h, évitez appels redondants (coût ~1$/k images).
  • Pré-traitez images : resize <4MP avec Sharp.js, booste vitesse/précision.
  • Quotas & coûts : limitez maxResults:5, monitor via Cloud Monitoring ; batch pour scale.
  • Streams pour gros fichiers : utilisez source: { stream: fs.createReadStream() } vs base64.
  • TypeScript strict : étendez types pour Landmark comme ci-dessus.

Erreurs courantes à éviter

  • Auth invalide : 'Region mismatch' → clé EU/US ? Utilisez projectId explicite dans client opts.
  • Base64 overflow : images >20MB crash → chunk ou GCS URI (image: { source: { gcsImageUri: 'gs://bucket/img.jpg' } }).
  • Hints ignorés : OCR faible sans languageHints ; testez fr-FR vs fr.
  • Async non géré : toujours try/catch + error.code pour retry (ex: RESOURCE_EXHAUSTED).

Pour aller plus loin

Approfondissez avec Vertex AI Vision pour modèles custom. Intégrez à Next.js App Router pour une API serverless. Ressources : Docs officielles Vision API, Codelab Google. Découvrez nos formations Learni sur Google Cloud IA pour certification pro.