Traitement d'images Canvas 2D : Principes et pratique des opérations pixel côté navigateur
Canvas dans le traitement d'images
Le navigateur offre trois voies de traitement d'images :
| Approche | Performance | Flexibilité | Mieux pour |
|---|---|---|---|
| Filtre CSS | Élevée (GPU) | Faible (filtres prédéfinis) | Effets visuels simples |
| Canvas 2D | Moyenne | Élevée (niveau pixel) | Compression, recadrage, conversion de format |
| WebGL | La plus élevée | Élevée (nécessite des shaders) | Filtres complexes, traitement en temps réel |
Les outils d'image de ToolsKu (compresser, recadrer, conversion de format, filigrane) sont tous construits sur l'API Canvas 2D.
Flux de traitement de base
// 1. Load image
const img = new Image();
img.src = URL.createObjectURL(file);
await img.decode();
// 2. Create Canvas and draw
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d')!;
ctx.drawImage(img, 0, 0);
// 3. Export to target format
const blob = await new Promise<Blob>((resolve) =>
canvas.toBlob(resolve, 'image/webp', 0.85) // quality 85%
);
Comment fonctionne la compression d'images
La compression Canvas est essentiellement un réencodage :
Original PNG (2MB, lossless)
↓ drawImage to Canvas
↓ toBlob('image/jpeg', 0.8)
Compressed JPEG (400KB, lossy 80% quality)
| Format | Compression | Ratio typique | Transparence |
|---|---|---|---|
| JPEG | DCT avec pertes | 60-80% | ❌ |
| WebP | Avec/sans pertes | 70-90% | ✅ |
| PNG | DEFLATE sans pertes | 10-30% | ✅ |
| AVIF | Avec/sans pertes | 80-95% | ✅ |
L'outil de compression d'images de ToolsKu prend en charge la compression par lots WebP/JPEG. La qualité par défaut de 85% équilibre la taille du fichier et la qualité visuelle.
Opérations au niveau pixel
Manipulez les pixels RGBA directement via ImageData :
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data; // Uint8ClampedArray, 4 bytes = 1 pixel
for (let i = 0; i < data.length; i += 4) {
// Grayscale
const avg = (data[i] + data[i+1] + data[i+2]) / 3;
data[i] = data[i+1] = data[i+2] = avg;
}
ctx.putImageData(imageData, 0, 0);
Optimisation des performances avec OffscreenCanvas
Les opérations Canvas sur le thread principal bloquent l'UI. OffscreenCanvas peut s'exécuter dans un Worker :
// worker.ts
const offscreen = new OffscreenCanvas(width, height);
const ctx = offscreen.getContext('2d')!;
ctx.drawImage(imageBitmap, 0, 0);
const blob = await offscreen.convertToBlob({ type: 'image/webp', quality: 0.85 });
postMessage({ blob }, [blob]); // Transferable
Lors du traitement par lots de 50 images, OffscreenCanvas + Worker réduit le blocage du thread principal de 10s à 0.
Questions fréquentes
Pourquoi l'image semble floue après la compression ?
La compression avec pertes JPEG/WebP supprime les détails haute fréquence. Augmentez le paramètre de qualité (0.9+) ou utilisez le mode sans pertes PNG/WebP.
Y a-t-il des limites de taille pour Canvas ?
La plupart des navigateurs limitent un seul bord de Canvas à 16384px, avec une superficie totale d'environ 268MP. Le dépassement nécessite un traitement par tuiles.
Comment gérer l'orientation EXIF ?
Les photos de téléphones peuvent inclure l'orientation EXIF. Lisez l'EXIF et faites pivoter le Canvas avant le dessin, sinon l'image apparaîtra tournée. Le Convertisseur de format d'image de ToolsKu gère l'EXIF automatiquement.
Résumé
Canvas 2D est l'approche standard pour le traitement d'images côté navigateur. Comprendre le pipeline d'encodage drawImage → toBlob, les opérations pixel avec ImageData et le déchargement vers Worker avec OffscreenCanvas est essentiel pour construire des outils d'image haute performance.
Essayez ces outils exécutés localement dans le navigateur — aucune inscription requise →