使用TypeScript处理图像:调整大小(resize)与裁剪(crop)
在现代Web开发中,客户端图像处理是一项常见任务。TypeScript凭借其严格的类型系统和对现代浏览器API的良好集成,能够安全高效地执行resize(调整大小)和crop(裁剪)操作。本文将介绍两种方法:使用原生Canvas API,以及使用适用于Node.js的服务器端库sharp和jimp。
1. Canvas API:无需依赖的客户端处理
浏览器中的HTMLCanvasElement是操作图像最简单的方式。它无需安装额外包,可在任何现代浏览器中运行。
1.1. 通过Canvas调整大小(resize)
核心思路是将原始图像以新尺寸绘制到canvas上,然后导出结果。
function resizeImage( source: HTMLImageElement, targetWidth: number, targetHeight: number): Promise<Blob> { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); canvas.width = targetWidth; canvas.height = targetHeight; const ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('Canvas context not supported')); return; } // 以新尺寸绘制图像 ctx.drawImage(source, 0, 0, targetWidth, targetHeight); // 导出为Blob(默认格式为PNG) canvas.toBlob((blob) => { if (blob) resolve(blob); else reject(new Error('Failed to create blob')); }, 'image/jpeg', 0.9); // 可指定格式和质量 });}重要提示:放大图像(upscale)时,质量可能会下降——canvas使用双线性插值。这对于预览可以接受,但不适用于打印。
1.2. 带坐标的裁剪(crop)
裁剪需要指定原始图像中的矩形区域。
function cropImage( source: HTMLImageElement, x: number, y: number, width: number, height: number): Promise<Blob> { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('Canvas not supported')); return; } // 从原始图像中裁剪出指定片段 ctx.drawImage(source, x, y, width, height, 0, 0, width, height); canvas.toBlob((blob) => { if (blob) resolve(blob); else reject(new Error('Blob creation failed')); }, 'image/png'); });}建议:始终检查坐标x, y, width, height是否超出原始图像边界,否则canvas将返回空白区域。
2. 服务器端处理:sharp和jimp
如果您在Node.js和TypeScript环境中工作,sharp(基于C++原生,高性能)和jimp(纯JS,跨平台)是标准解决方案。
2.1. 安装与导入
// 安装// npm install sharp// npm install jimp
import sharp from 'sharp';import Jimp from 'jimp';2.2. 使用sharp调整大小(resize)
async function resizeWithSharp( inputPath: string, outputPath: string, width: number, height: number): Promise<void> { await sharp(inputPath) .resize(width, height, { fit: 'cover', // 'cover' - 裁剪多余部分,'contain' - 保持比例完整显示 position: 'center' // 裁剪时的参考点 }) .toFile(outputPath);}参数fit决定了图像适应策略:
cover—