cropper.js是证件照裁剪最稳方案,支持比例锁定、旋转缩放且纯前端处理保障隐私;需等img.onload后初始化,容器设显式宽高,固定比例须设aspectratio(小数)、viewmode:1、dragmode:'crop';导出高清图需double canvas+scale;自定义尺寸须destroy后重建实例。

直接用 Cropper.js 是最省事、最稳的方案,它原生支持比例锁定、旋转、缩放,且不依赖后端——所有操作都在浏览器里完成,照片不会上传,符合证件照对隐私的基本要求。
图片加载完再初始化,否则黑屏或裁剪框错位
很多人初始化后看到黑图、空白或裁剪框卡在左上角,根本原因是 new Cropper(image, {...}) 被提前执行了,而 <img> 的 src 还没加载完。
- 必须用
img.onload回调包裹初始化逻辑,不能只等DOMContentLoaded或$(document).ready() - 容器(如
<div id="cropper-container">)要设显式 <code>width和height,不能靠内容撑开或写min-height - 避免在
display: none的父元素中初始化;若需初始隐藏,改用visibility: hidden或先初始化再隐藏 - Webpack/Vite 项目注意静态资源路径:控制台报 404 会导致
onload不触发,src必须能真实加载成功 -
aspectRatio: 295 / 413—— 必须是小数(≈0.714),不能写字符串"295/413"或数组[295, 413] -
viewMode: 1—— 允许裁剪框越出图片边界,否则人像稍大就框不住头顶和下巴 -
dragMode: 'crop'—— 默认是'move',那是拖整张图,不是拉裁剪框;不设这个,用户点半天拉不出框
固定比例裁剪必须设对三个参数
一寸照(295×413)、二寸(413×579)、护照(33×48mm 换算像素)等标准尺寸,靠 aspectRatio 锁定,但光写这个不够。
示例:
const image = document.getElementById('image');
image.onload = () => {
const cropper = new Cropper(image, {
aspectRatio: 295 / 413,
viewMode: 1,
dragMode: 'crop',
rotatable: true,
scalable: true
});
};
导出高清图必须 double canvas + scale,否则打印模糊
cropper.getCroppedCanvas() 默认输出 1x 像素密度画布,直接转成 toDataURL 或 toBlob 下载,PPI 只有 96,A4 打印出来就是马赛克。
- 先调
cropper.getData()拿到原始图像上的裁剪坐标和尺寸(单位:px) - 创建新
<canvas></canvas>,width/height设为所需输出尺寸 × 2(例如一寸 590×826) - 用
ctx.scale(2, 2)缩放绘图上下文,再把cropper.getCroppedCanvas()的内容绘制进去 - 漏掉
scale这一步,尺寸看着对,实际分辨率不足;别信“导出尺寸对就行”这种经验
自定义尺寸后裁剪框没更新?大概率没重建实例
用户选“自定义”,填了宽高,点“应用”,结果裁剪框比例纹丝不动——这不是 bug,是误用了 API。
-
cropper.setAspectRatio()只影响后续新建的裁剪框,不会重置当前已存在的裁剪框尺寸 - 真正生效的方式是:先
cropper.destroy(),再用新aspectRatio重新new Cropper(...) - 尤其要注意 DOM 时机:新
<img>替换后,必须等新图onload完再重建,否则又黑屏
复杂点在于:旋转角度非 90° 倍数时,getCroppedCanvas() 返回的画布会带留白,必须显式传参指定宽高,否则导出图边缘全是透明或黑边。











