Trabajo con imágenes en TypeScript: resize y crop
\nEn el desarrollo web moderno, el procesamiento de imágenes es una de las tareas más demandadas. TypeScript, gracias a su tipado estricto e integración con Node.js, permite crear herramientas robustas y eficientes para cambiar el tamaño (resize) y recortar (crop) imágenes. En este artículo, veremos dos librerías populares: Sharp (procesamiento del lado del servidor) y Jimp (JavaScript puro), así como un enfoque nativo usando Canvas API para el navegador.
\n\n1. Instalación y configuración de un proyecto TypeScript
\nPara empezar, crea un proyecto e instala las dependencias necesarias:
\nnpm init -y\nnpm install typescript @types/node sharp jimp\nnpx tsc --init\nEn el archivo tsconfig.json, asegúrate de tener "module": "commonjs" y "target": "ES2020".
2. Librería Sharp — procesamiento rápido del lado del servidor
\nSharp utiliza el módulo nativo libvips y ofrece un alto rendimiento. Es adecuado para aplicaciones del lado del servidor (NestJS, Express).
\n\n2.1. Cambio de tamaño (resize) con Sharp
\nEl método resize() acepta ancho y alto. Puedes especificar solo un parámetro; el segundo se calculará proporcionalmente.
import sharp from 'sharp';\n\nasync function resizeImage(inputPath: string, outputPath: string, width: number, height?: number): Promise<void> {\n try {\n await sharp(inputPath)\n .resize(width, height, {\n fit: 'cover', // 'cover', 'contain', 'fill', 'inside', 'outside'\n position: 'center' // posición para el recorte al usar cover\n })\n .toFile(outputPath);\n console.log(`Imagen redimensionada: ${outputPath}`);\n } catch (error) {\n console.error('Error en resize:', error);\n }\n}\n\n// Ejemplo de uso\nresizeImage('input.jpg', 'output_800x600.jpg', 800, 600);\n\n2.2. Recorte (crop) con Sharp
\nEl método extract() permite recortar un área rectangular. Parámetros: left, top, width, height.
async function cropImage(\n inputPath: string,\n outputPath: string,\n left: number,\n top: number,\n cropWidth: number,\n cropHeight: number\n): Promise<void> {\n try {\n await sharp(inputPath)\n .extract({ left, top, width: cropWidth, height: cropHeight })\n .toFile(outputPath);\n console.log(`Recorte realizado: ${outputPath}`);\n } catch (error) {\n console.error('Error en crop:', error);\n }\n}\n\n// Ejemplo: recortar el centro 400x400 de una imagen de 800x600\ncropImage('input.jpg', 'cropped_center.jpg', 200, 100, 400, 400);\n\n2.3. Combinación de resize y crop
\nSharp permite encadenar operaciones. Por ejemplo, primero reducir y luego recortar:
\nasync function resizeAndCrop(inputPath: string, outputPath: string): Promise<void> {\n await sharp(inputPath)\n .resize(500, 500, { fit: 'inside' }) // reducimos a 500x500 sin recortar\n .extract({ left: 50, top: 50, width: 400, height: 400 }) // recortamos el centro\n .toFile(outputPath);\n}\n\nresizeAndCrop('input.jpg', 'processed.jpg');\n\n3. Librería Jimp — JavaScript puro sin dependencias nativas
\nJimp funciona con JavaScript puro, no requiere instalar librerías de sistema adicionales. Es ideal para entornos aislados (por ejemplo, AWS Lambda).
\n\n3.1. Instalación de Jimp
\nnpm install jimp\nnpm install @types/jimp // para TypeScript\n\n3.2. resize con Jimp
\nimport Jimp from 'jimp';\n\nasync function resizeWithJimp(inputPath: string, outputPath: string, width: number, height: number): Promise<void> {\n try {\n const image = await Jimp.read(inputPath);\n image.resize(width, height, Jimp.RESIZE_BILINEAR); // algoritmos: BILINEAR, BICUBIC, NEAREST_NEIGHBOR\n awa