drawimage方法通过9参数形式可实现裁剪并等比缩放:先按目标宽高比居中计算裁剪区域(sx,sy,sw,sh),再缩放绘制到目标位置(dx,dy,dw,dh)。

Canvas 的 drawImage 方法本身不直接提供“裁剪并等比缩放”功能,但可以通过合理设置 9 个参数(即完整版 drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh))手动实现:先从原图中截取一个等比例的中心区域(裁剪),再将其绘制到目标位置并缩放到指定尺寸(缩放)。关键在于计算裁剪区域的起始坐标和宽高。
明确裁剪目标:先确定“等比例”的参照标准
等比例裁剪通常指:从原图中截取一个与目标画布(或目标显示区域)宽高比相同的矩形区域,并尽量保留图像主体(一般选居中截取)。例如要把一张 1200×800 的图,等比裁成 400×300 的显示区域,两者宽高比都是 4:3,可直接居中取;若原图是 1200×900(4:3),目标是 400×300(4:3),也匹配;但若原图是 1200×800(3:2),目标是 400×300(4:3),就需要选择按宽还是按高来对齐——常见策略是“缩放后居中裁剪”,即先等比缩放到目标宽高比,再取中间部分。
计算裁剪区域(sx, sy, sw, sh)
假设原图尺寸为 img.width × img.height,目标显示区域宽高为 targetW × targetH:
- 计算原图和目标的宽高比:
imgRatio = img.width / img.height,targetRatio = targetW / targetH - 若
imgRatio >= targetRatio(原图更宽或一样宽):以高度为基准,裁剪高度 = 原图高度,宽度按目标比例扩展 →sw = img.height * targetRatio,sh = img.height,sx = (img.width - sw) / 2,sy = 0 - 若
imgRatio (原图更高):以宽度为基准 → <code>sw = img.width,sh = img.width / targetRatio,sx = 0,sy = (img.height - sh) / 2
调用 drawImage 完成绘制
得到裁剪区域 (sx, sy, sw, sh) 后,直接映射到目标位置 (dx, dy, dw, dh)(通常就是你要显示的区域,如 0, 0, targetW, targetH):
ctx.drawImage(img, sx, sy, sw, sh, 0, 0, targetW, targetH);
这行代码含义是:从原图 (sx,sy) 开始,截取 sw×sh 区域,拉伸/压缩绘制到 Canvas 上的 0,0,targetW,targetH 矩形中。因裁剪区域与目标区域宽高比一致,结果无拉伸变形,且内容居中。
封装为可复用函数
实际使用时建议封装逻辑,避免每次重复计算:
function drawImageCenterCrop(ctx, img, dx, dy, dw, dh) {
const imgRatio = img.width / img.height;
const targetRatio = dw / dh;
let sx, sy, sw, sh;
<p>if (imgRatio >= targetRatio) {
// 原图更宽:固定高度,水平居中裁剪
sh = img.height;
sw = img.height * targetRatio;
sx = (img.width - sw) / 2;
sy = 0;
} else {
// 原图更高:固定宽度,垂直居中裁剪
sw = img.width;
sh = img.width / targetRatio;
sx = 0;
sy = (img.height - sh) / 2;
}</p><p>ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
}</p><p>// 使用示例
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
drawImageCenterCrop(ctx, img, 0, 0, 400, 300);
};
img.src = 'photo.jpg';</p>前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











