Procesamiento de imágenes con Canvas 2D: Principios y práctica de operaciones de píxeles del lado del navegador
Canvas en el procesamiento de imágenes
El navegador ofrece tres rutas de procesamiento de imágenes:
| Enfoque | Rendimiento | Flexibilidad | Mejor para |
|---|---|---|---|
| Filtro CSS | Alto (GPU) | Baja (filtros predefinidos) | Efectos visuales simples |
| Canvas 2D | Medio | Alta (nivel de píxel) | Compresión, recorte, conversión de formato |
| WebGL | El más alto | Alta (requiere shaders) | Filtros complejos, procesamiento en tiempo real |
Las herramientas de imagen de ToolsKu (comprimir, recortar, conversión de formato, marca de agua) están todas construidas sobre la API Canvas 2D.
Flujo de procesamiento básico
// 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%
);
Cómo funciona la compresión de imágenes
La compresión con Canvas es esencialmente recodificación:
Original PNG (2MB, lossless)
↓ drawImage to Canvas
↓ toBlob('image/jpeg', 0.8)
Compressed JPEG (400KB, lossy 80% quality)
| Formato | Compresión | Ratio típico | Transparencia |
|---|---|---|---|
| JPEG | DCT con pérdida | 60-80% | ❌ |
| WebP | Con pérdida/sin pérdida | 70-90% | ✅ |
| PNG | DEFLATE sin pérdida | 10-30% | ✅ |
| AVIF | Con pérdida/sin pérdida | 80-95% | ✅ |
La herramienta de compresión de imágenes de ToolsKu soporta compresión por lotes WebP/JPEG. La calidad predeterminada del 85% equilibra el tamaño del archivo y la calidad visual.
Operaciones a nivel de píxel
Manipula píxeles RGBA directamente a través de 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);
Optimización de rendimiento con OffscreenCanvas
Las operaciones de Canvas en el hilo principal bloquean la UI. OffscreenCanvas puede ejecutarse en 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
Al procesar por lotes 50 imágenes, OffscreenCanvas + Worker reduce el bloqueo del hilo principal de 10s a 0.
Preguntas frecuentes
¿Por qué la imagen se ve borrosa después de la compresión?
La compresión con pérdida de JPEG/WebP descarta detalles de alta frecuencia. Aumenta el parámetro de calidad (0.9+) o usa el modo sin pérdida de PNG/WebP.
¿Hay límites de tamaño para Canvas?
La mayoría de los navegadores limitan un solo borde de Canvas a 16384px, con un área total de aproximadamente 268MP. Exceder esto requiere procesamiento en mosaicos.
¿Cómo se maneja la orientación EXIF?
Las fotos de teléfonos pueden incluir EXIF Orientation. Lee EXIF y rota el Canvas antes de dibujar, o la imagen aparecerá girada. El Convertidor de formato de imagen de ToolsKu maneja EXIF automáticamente.
Resumen
Canvas 2D es el enfoque estándar para el procesamiento de imágenes del lado del navegador. Comprender el pipeline de codificación drawImage → toBlob, las operaciones de píxeles con ImageData y la descarga a Worker con OffscreenCanvas es fundamental para construir herramientas de imagen de alto rendimiento.
Prueba estas herramientas que se ejecutan en tu navegador — no requieren registro →