canvas图片等比缩放+居中裁剪导出需用drawimage九参数法:先依宽高比确定裁剪基准(宽图按高、高图按宽),再计算居中裁剪区域(sx,sy,sw,sh),最后一步映射到目标尺寸,避免失真;导出支持blob或data url。

在 Canvas 中实现图片等比例缩放 + 居中裁剪导出,核心是用 drawImage 的 9 参数形式,先算出与目标宽高比一致的中心裁剪区域,再无拉伸地绘制到目标尺寸。不是“先缩放再裁剪”,而是“按比例选区域,再精准映射”——这样能保留原始像素质量,避免双重缩放失真。
一、明确目标宽高比,决定裁剪基准
假设原图尺寸为 img.width × img.height,你要导出的尺寸是 targetW × targetH(比如 400×300):
- 计算两者宽高比:
imgRatio = img.width / img.height,targetRatio = targetW / targetH - 若
imgRatio >= targetRatio(原图更宽或等宽)→ 以高度为基准:裁剪高度用满原图高,宽度按目标比例反推,居中取横轴 - 若
imgRatio (原图更高)→ 以宽度为基准:裁剪宽度用满原图宽,高度按目标比例反推,居中取纵轴
二、计算裁剪区域坐标(sx, sy, sw, sh)
这是最关键的一步,直接决定是否真正“等比+居中”:
- 当
imgRatio >= targetRatio(宽图 → 按高裁):sh = img.heightsw = img.height * targetRatiosx = (img.width - sw) / 2sy = 0 - 当
imgRatio (高图 → 按宽裁):<br><code>sw = img.widthsh = img.width / targetRatiosx = 0sy = (img.height - sh) / 2
三、用 drawImage 一次性完成裁剪+缩放绘制
把上一步算出的裁剪区域,直接映射到目标画布的完整区域(0, 0, targetW, targetH):
ctx.drawImage(img, sx, sy, sw, sh, 0, 0, targetW, targetH);
这行代码做了两件事:从原图截取 sw×sh 区域(已保证与 targetW×targetH 宽高比一致),再把它**等比填充**到目标矩形中。结果图像无变形、内容居中、边缘无黑边。
四、导出为图片文件(Blob 或 Data URL)
裁剪绘制完成后,调用 canvas 原生方法导出:
- 导出为 Blob(推荐用于上传):
canvas.toBlob(blob => { /* 上传或下载 */ }, 'image/jpeg', 0.9); - 导出为 Base64 URL(适合预览):
const url = canvas.toDataURL('image/jpeg', 0.9);
注意:导出格式和质量参数(如 0.9)可按需调整;JPEG 更小,PNG 支持透明;若原图含 alpha 通道且需保留,优先用 PNG。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











