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 →

#Canvas#图像处理#WebGL#像素操作#性能