cropper - 基于jquery的图片裁剪插件详解

东门越
2023-12-01

cropper插件的使用参考

官方示例:https://fengyuanchen.github.io/cropper/
github上详细说明文档(官方文档,全英文):https://github.com/fengyuanchen/cropper/blob/v2.3.4/README.md#options
我认为写的比较好的中文讲解(附示例demo,本文主要参考对象):http://www.qingpingshan.com/jb/javascript/359021.html

cropper介绍

兼容所有支持了Canvas的浏览器(IE9+),一小部分功能例外,对移动端操作也有适配,支持裁剪、旋转、翻转等,具体请查看官方文档。

但是它并没有对图片真正的处理,只是记录了用户做了哪些变换,然后需要自己再去处理

cropper使用

一、使用前准备:

  1. 引入源文件

  2. 可先定义一个用于存放未裁剪图像的容器,里面放一个有id属性和src属性(可以是本地路径/网络路径/使用微信JSSDK选定照片的本地ID/blob的形式/base64格式/…)的img,如:<div><img src="http://oyd8w2s7w.bkt.clouddn.com/2018/08/23/3147b2e4-748e-4c22-95fc-62695c2d3320.jpg" alt="" id="photo"></div>,在裁剪的时候cropper会查找这个id,并在其后操作DOM。

二、option参数:var options = { '参数1': '值1', '参数2': '值2'}; $("#photo").cropper(options); 不完整,想了解全部参数可查看官方API文档

  • viewMode:0(默认) [1 / 2 / 3] 对需裁剪图片缩放&移动的限制。其中:0(没有限制)、1(图片缩放时最小不能小于裁剪框,可任意移动)、2(图片缩放时最小不能小于它的外容器,图片移动时上下或左右必须贴着外容器)、3(图片缩放时最小不能小于它的外容器,图片移动时上下左右都必须贴着外容器)
  • dragMode: 'crop'(默认) ['move' / 'none'] 其中:crop(当鼠标点击裁剪框外的一处时根据这个点重新生成一个 裁剪框)、move(可以拖动图片)、none(什么也不做)
  • aspectRatio: 宽 / 高 值为裁剪框的宽高比(默认NaN)
  • preview: str 值为显示预览图的容器选择器,如 div.box
  • responsive: true [false] 是否响应式,在调整窗口大小时重新渲染裁剪器
  • modal: true [false] 是否显示裁剪框外的黑色半透明背景
  • cropBoxMovable: true [false] 是否允许拖动改变裁剪框大小,默认true
  • guides: true [false] 是否显示裁剪框上的虚线
  • center:true [false] 是否显示裁剪框上的中心指示器
  • highlight: true [false] 是否高亮显示裁剪框中的图像
  • movable: true [false] 是否允许移动图像
  • rotatable: true [false] 是否允许旋转图像
  • scalable: true [false] 是否允许缩放图像

事件相关

  • ready:初始化完成,只调用一次
  • cropstart:移动(裁剪框或图片)开始
  • cropmove:移动(裁剪框或图片)
  • cropend:移动(裁剪框或图片)结束
  • crop:当画布或裁剪框改变时
  • zoom:图片缩放事件

三、Methods方法(如需要将裁剪后的图像上传给服务器,请仔细看下面的getCroppedCanvas方法

由于cropper是异步加载的,所以除 setAspectRatio 和 destroy 之外的事件都应该放在ready事件参数中(下面的方法列表说明都是放在ready内的,重复的代码就不再写了):

$("#photo").cropper({
  ready: function () {
    $(this).cropper('method', argument1, , argument2, ..., argumentN);
  }
});
  • crop():手动显示裁剪框
autoCrop: false,
ready: function () {
    $(this).cropper('crop');
}
  • reset():将图像和裁剪框重置为初始状态

  • clear():清除裁剪框

  • replace(url[, onlyColorChanged]):替换图像的 url 并重建cropper
    • url:新的图片url地址
    • onlyColorChanged :默认值为false,如果只改变颜色,而不改变大小,那么cropper只需要改变所有相关图像的src,而不需要重建cropper。这可以用于filters应用
  • disable():冻结(禁用)cropper
  • enable():解冻 cropper
  • destroy():销毁cropper,并从图像中删除实例
  • move(offsetX[, offsetY]):值为number类型,分别表示水平/垂直 方向的移动尺寸(px值,offsetY默认值同offsetX)。$(this).cropper('move', 1, -1);
  • moveTo(x[, y]):将画布(图像的容器)移动到绝对点。值为number类型,x, y分别表示画布的 left / top 值(y默认值同x)
  • zoom(ratio):以相对比例缩放画布(图像的容器)。值为number类型,ratio>0时放大,ratio<0时缩小。$(this).cropper('zoom', -0.1);
  • zoomTo(ratio):缩放画布(图像的容器)到绝对比率。值为number类型
  • rotate(degree):以相对角度旋转图像。值为number类型,正数向右旋转,负数向左旋转。$(this).cropper('rotate', 90);
  • rotateTo(degree):旋转图像到绝对角度
  • scale(scaleX[, scaleY]):缩放图像。值为number类型,参数分别表示图像在横 / 纵坐标上的缩放(scaleX默认值为1、scaleY默认值同scaleX)。$(this).cropper('scale', -1, 1);
  • scaleX(scaleX):图像在横坐标上的缩放。值为number类型(默认值为1)
  • scaleY(scaleY):图像在纵坐标上的缩放。值为number类型(默认值为1)
  • getData([rounded]):默认值为false,设置true可获得舍入值。var getData = $image.cropper("getData");有object类型的记录用户操作的返回值,可将此返回值发送给服务器端以直接输出图像。其中:
    • x:裁剪框左边的偏移量
    • y:裁剪框顶部的偏移量
    • width:裁剪框的宽
    • height:裁剪框的高
    • rotate:图像旋转角度
    • scaleX:图像在横坐标上的缩放
    • scaleY:图像在纵坐标上的缩放
  • setData(data):用新数据(基于原始图像)改变裁剪框的位置和大小(注意:此方法仅在 viewmode 选项大于或等于1时可用)。data参数为与getData()返回值相同的Object对象,如:$(this).cropper("setData", { x: 203, y: 491, width: 393, height: 393, rotate: 90, scaleX: 2, scaleY: 2 });
  • getContainerData():返回容器大小数据,object类型,参数为:包含容器的当前宽 / 高度
  • getImageData():返回object类型的图像的位置、大小等相关数据:{ left: 0, top: 0, width: 700, height: 393.75, naturalWidth: 1280, naturalHeight: 720, aspectRatio: 1.7, rotate: 0, scaleX: 1, scaleY: 1 }。参数为:图像的左偏移量、图像的上偏移量、图像的宽、图像的高、图像的自然宽度、图像的自然高度、图像的纵横比、图像的旋转角度、图像在横坐标上的缩放、图像在纵坐标上的缩放
  • getCanvasData():返回object类型的画布(图像的容器)的位置和大小数据:{ left: 115.7, top: -241.4, width: 476.4, height: 847.0, naturalWidth: 720, naturalHeight: 1280 }。参数为:图像的左偏移量、图像的上偏移量、图像的宽、图像的高、图像的自然宽度、图像的自然高度
  • setCanvasData(data):用新数据更改画布(图像包装器)的位置和大小。data参数为Object类型:{ left: 画布左边的新偏移量, top: 画布上边的新偏移量, width: 画布的新宽度, height: 画布的新高度 }
  • getCropBoxData():输出object类型的裁剪框的位置和大小数据:{ left: 裁剪框左侧的偏移量, top: 裁剪框上边的偏移量, width: 裁剪框的宽度, height: 裁剪框的高度 }
  • setCropBoxData(data):用新数据更改裁剪框的位置和大小。data参数为Object类型:{ left: 裁剪框左边的新偏移量, top: 裁剪框上边的新偏移量, width: 裁剪框的新宽度, height: 裁剪框的新高度 }
  • getCroppedCanvas([options])
    • options对象参数:width(输出画布的指定宽度)、height(输出画布的指定高度)、minWidth(输出画布的最小目标宽度,默认值为0)、minHeight(输出画布的最小目标高度,默认值为0)、maxWidth(输出画布的最大目标宽度,默认值为0)、maxHeight(输出画布的最大目标高度,默认值为0)、fillColor(用于填充输出画布中任何alpha值的颜色,默认值是透明的)、imageSmoothingEnabled(设置图像是否平滑,默认true)、imageSmoothingQuality(设置图像平滑的质量,low(默认) / high)
    • 返回值:画出剪裁图像的画布(一个canvas DOM)
    • 注意:1)输出画布的长宽比将自动拟合到裁剪框的长宽比(可以理解为把裁剪框内的图像拉伸为options中指定的宽高);2) 如果希望从输出画布中获取JPEG图像,应该首先设置fillColor选项,否则JPEG图像中的透明部分将默认为黑色;
    • 重要:可以用此返回值调用(如果浏览器支持这些API):1) HTMLCanvasElement .toDataURL 获取base64格式的数据、2) HTMLCanvasElement .toBlob 获取blob,直接将画布显示为图像,且可使用FormData将其上传到服务器
//var base64 = $(this).cropper('getCroppedCanvas',{ width:750, height:582 }).toDataURL('image/png');
//$target.attr('src', base64);

$(this).cropper('getCroppedCanvas', {
  width: 160,
  height: 90,
  fillColor: '#fff'
}).toBlob(function (blob) {
  var formData = new FormData();
  formData.append('croppedImage', blob);
  $.ajax('/path/to/upload', {
    method: "POST",
    data: formData,
    processData: false,
    contentType: false,
    success: function () {
      console.log('Upload success');
    },
    error: function () {...}
  });
});;
  • setAspectRatio(aspectRatio):改变裁剪框的长宽比,参数为一个正数
  • setDragMode([mode]):改变拖曳模式。可以通过双击裁剪框来切换crop和move。mode可选:’none’ / ‘crop’ / ‘move’,默认none

cropper示例

  • 基础实例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
    <style>
        #imgBox { width: 700px }
        #photo { max-width: 100% }
        .img-preview { width: 150px; height: 150px; display: inline-block; margin-top: 10px; overflow: hidden }
        .showImgBox { width: 140px; height: 140px; display: inline-block }
        #showImg { max-width: 100% }
    </style>
</head>
<body>
    <div id="imgBox">
        <img src="http://oyd8w2s7w.bkt.clouddn.com/2018/08/23/3147b2e4-748e-4c22-95fc-62695c2d3320.jpg" alt="" id="photo">
    </div>
    <div class="img-preview"></div>
    <button type="button" id="clipImg">裁剪图片</button>
    <div class="showImgBox">
        <img src="" id="showImg" alt="裁剪结果">
    </div>
    <br>
    <button type="button" id="toLeft">左转90度</button>
    <button type="button" id="toRight">右转90度</button>

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
<script>
    $(function(){
        var $image = $("#photo");
        $image.cropper({
            aspectRatio: 1,
            dragMode: 'move',
            viewMode: 1,
            cropBoxResizable: false,
            preview: '.img-preview',
            ready: function(){
                $("#toRight").on("click", function(){ $image.cropper('rotate', 90) });
                $("#toLeft").on("click", function(){ $image.cropper('rotate', -90) });
                $("#clipImg").on("click", function(){
                    $image.cropper('getCroppedCanvas',{
                        width:140,   // 裁剪后的长宽
                        height:140
                    }).toBlob(function(blob){
                        $("#showImg").attr('src', URL.createObjectURL(blob));    // 将裁剪后的图片放到指定标签展示
                    });
                });
            }
        });
    });
</script>
</body>
</html>
  • input type=file上传文件并上传到服务器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>裁剪图片</title>
    <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
    <style>
        #photo { max-width: 100% }
        .img-preview { width: 100px; height: 100px; overflow: hidden }
        #selectImg { width: 375px; height: 150px }
    </style>
</head>
<body>
<form id="form">
    <!--表单部分-->
    <div>
        <label>选择图片</label>
        <span>
            <img src="" alt="裁剪结果" id="selectImg" style="display: none">
            <input type="file" id="imgInp" class="sr-only" style="display: none">
            <button type="button" class="pictureUrl" onclick="$('#imgInp').click()" id="uploadImg">选择图片</button>
        </span>
    </div>
</form>

<div id="cropperBox">
    <!--裁剪部分-->
    <div>
        <img src="" id="photo">
    </div>
    <!--预览提示、裁剪操作-->
    <p>预览 <button class="btn btn-primary" onclick="crop()">裁剪图片</button></p>
    <!--预览-->
    <div class="img-preview"></div>
</div>

<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
<script>
    var initCropper = function (img, input){
        var $image = img;
        var options = {
            aspectRatio: 5 / 2,
            dragMode: 'move',
            viewMode: 1,
            cropBoxResizable: false,
            preview: '.img-preview'
        };
        $image.cropper(options);
        var $inputImage = input;
        var uploadedImageURL;
        if (URL) {
            $inputImage.change(function () {  // 给input添加监听
                $("#form").hide();
                $("#cropperBox").slideDown();
                var files = this.files;
                var file;
                if (!$image.data('cropper')) {
                    return;
                }
                if (files && files.length) {
                    file = files[0];
                    if (/^image\/\w+$/.test(file.type)) {   // 判断是否是图像文件
                        if (uploadedImageURL) {   // 如果URL已存在就先释放
                            URL.revokeObjectURL(uploadedImageURL);
                        }
                        uploadedImageURL = URL.createObjectURL(file);
                        // 销毁cropper后更改src属性再重新创建cropper
                        $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
                        $inputImage.val('');
                    } else {
                        window.alert('请选择一个图像文件!');
                    }
                }
            });
        } else {
            $inputImage.prop('disabled', true).addClass('disabled');
        }
    };
    var crop = function(){
        var $image = $('#photo');
        var $target = $('#selectImg');
        $image.cropper('getCroppedCanvas',{
            width:750,
            height:300
        }).toBlob(function(blob){
            $("#form").show();
            $("#cropperBox").slideUp();
            $("#selectImg").show();
            $target.attr('src', URL.createObjectURL(blob));    // 将裁剪后的图片放到指定标签
            var formData = new FormData();      // 将裁剪后的图片上传到服务器
            formData.append('croppedImage', blob);
            $.ajax('/uploadImg', {
                method: "POST",
                data: formData,
                processData: false,
                contentType: false,
                success: function () { }
            });
        });
    };
    $(function(){
        initCropper($('#photo'),$('#imgInp'));
    });
</script>
</body>
</html>
  • 使用微信JSSDK选择图片并得到裁剪后的base64位的图片(可直接将base64的数据传给服务器)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>裁剪图片</title>
    <link href="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.css" rel="stylesheet">
    <style>
        #photo { max-width: 100% }
        .img-preview { width: 100px; height: 100px; overflow: hidden }
        #selectImg { width: 375px; height: 150px }
    </style>
</head>
<body>
    <form id="form">
        <img src="" alt="裁剪结果" id="selectImg" style="display: none">
        <button type="button" class="pictureUrl" id="uploadImg">选择图片</button>
    </form>
    <!--裁剪部分-->
    <div id="cropperBox">
        <div><img src="" id="photo"></div>
        <button class="btn btn-primary" onclick="crop()">裁剪图片</button>
        <!--预览-->
        <div class="img-preview"></div>
    </div>

    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    <script src="https://cdn.bootcss.com/cropper/3.1.3/cropper.min.js"></script>
        $.ajax({   //微信验证
           url: "wechat/getSignature",
            type: "post",
            data: { "url": window.location.href },
            dataType: "json",
            success: function (data) {
                wx.config({
                    appId: data.data.appId,
                    timestamp: data.data.timestamp,
                    nonceStr: data.data.nonceStr,
                    signature: data.data.signature,
                    jsApiList: ['chooseImage','uploadImage']
                });
            }
        });
        $("#uploadImg").on("click", function(){    //点击选择图片
            wx.chooseImage({
                count: 1,
                sizeType: ['original'],
                success: function(res) {
                    var url = res.localIds[0];
                    $("#photo").cropper('destroy').attr('src', url).get(0).onload = function(){
                        $(this).cropper({
                            aspectRatio: 125 / 97,
                            dragMode: 'move',
                            viewMode: 1,
                            cropBoxResizable: false,
                            preview: '.img-preview'
                        });
                    };
                    $("#coupon").hide();
                    $("#cropperBox").show();
                }
            });
        });
        var crop = function(){     //开始裁剪图片
            var $image = $('#photo');
            var $target = $('#selectImg');
            var base64 = $image.cropper('getCroppedCanvas',{
                width:750,     //裁剪后的宽高(最终想要的图片尺寸)
                height:582
            }).toDataURL('image/png');
            $target.attr('src', base64); //裁剪后将图片放到指定标签
            $("#coupon").show();
            $("#cropperBox").hide();
            $(".selectImg").removeClass("hide");
        };
    </script>
</body>
</html>
 类似资料: