h5利用cropper.js实现图片裁剪

最近为了实现h5图片裁剪功能,在网上查阅了很多资料,最后找到cropper.js非常好用,以此记录下实现过程:

关于cropper.js

cropper是一款使用简单且功能强大的图片剪裁js插件。该图片剪裁插件支持图片放大缩小,支持鼠标滚轮操作,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用
官方网站:http://fengyuanchen.github.io/cropper/

前端图片裁剪处理

  1. 引入cropper文件,初始化文档结构
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./cropper.min.css">
</head>
<body>
    <!--文件上传-->
    <input type="file" class="js-uploadfile">
    <!--确定裁剪-->
    <input type="button" class="js-ok" value="裁剪">   
    <!--cropper基本结构-->
    <div class="container js-container">
        <img class="js-image" src="">
    </div>
    <!--裁剪结果显示-->
    <br/>
    <div class="js-result"></div>
    <script src="./jquery-1.10.1.min.js"></script>
    <script src="./cropper.min.js"></script>
    <script>//其他js代码</script>
</body>
</html>

以上代码包含文件上传,裁剪按钮和cropper基本结构,打好结构架子,下面就是功能的实现

  1. 核心js代码,实现功能有:
  • 文件上传
  • 图片裁剪
  • 图片提交

根据input[type=file]的值变化获取图片的base64文件信息

var cropper;
$(".js-uploadfile").on("change", function () {
    var fr = new FileReader();
    var file = this.files[0];

    if (!/image\/\w+/.test(file.type)) {
        showTips(file.name + "不是图片文件!");
        return false;
    } else if (file.size > 2 * 1024 * 1024) {
        showTips('图片大小不能超过2M');
        return false;
    }

    fr.readAsDataURL(file);
    fr.onload = function () {
        //这里初始化cropper
        console.log(fr);
        $('.js-image').attr('src',fr.result);
        iniCropper()
    };
});

然后初始化cropper,参数解释参考官方文档

var croppable = false;
function iniCropper() {
    var $image = $('.js-image'),
        image = $image[0];            
    cropper = new Cropper(image, {
        dragMode: 'move',
        aspectRatio: 1,
        autoCropArea: 0.65,
        restore: false,
        viewMode: 1,
        guides: false,
        center: false,
        highlight: false,
        cropBoxMovable: false,
        cropBoxResizable: false,
        toggleDragModeOnDblclick: false,
        ready: function () {
            croppable = true;
        }
    });
}

实现裁剪,并上传图片。这里需要调用两个函数getRectCanvas,convertBase64UrlToBlob:
getRectCanvas:用于绘制矩形Canvas,
convertBase64UrlToBlob:将以base64的图片url数据转换为Blob

$('.js-ok').on('click', function () {
    var croppedCanvas;
    var rectCanvas;
    var rectImage;

    if (!croppable) {
        return false;
    }
    // Crop
    croppedCanvas = cropper.getCroppedCanvas();
    //Rect 
    rectCanvas = getRectCanvas(croppedCanvas);
    // Show
    rectImage = document.createElement('img');
    rectImage.src = rectCanvas.toDataURL();     
  
    $('.js-result').html('').append(rectImage);

    //var form=document.forms[0];
    var formData = new FormData();   //这里连带form里的其他参数也一起提交了,如果不需要提交其他参数可以直接FormData无参数的构造函数  

    //convertBase64UrlToBlob函数是将base64编码转换为Blob  
    formData.append("filename", convertBase64UrlToBlob(rectCanvas.toDataURL()));  //append函数的第一个参数是后台获取数据的参数名,和html标签的input的name属性功能相同
    //ajax 提交form 

    return false;//不提交 
    $.ajax({
        url: '',
        type: "POST",
        data: formData,
        dataType: "text",
        processData: false,         // 告诉jQuery不要去处理发送的数据  
        contentType: false,        // 告诉jQuery不要去设置Content-Type请求头  

        success: function (res) {
            var data = JSON.parse(res);
            if (data.status) {
                hideLoading();
                showTips(data.msg);
                setTimeout(function () {
                    location.href = 'url?t=' + (new Date()).getTime();
                }, 200);
            } else {
                console.log(data);
            }
        },
        xhr: function () {            //在jquery函数中直接使用ajax的XMLHttpRequest对象  
            var xhr = new XMLHttpRequest();
            xhr.upload.addEventListener("progress", function (evt) {
                if (evt.lengthComputable) {
                    var percentComplete = Math.round(evt.loaded * 100 / evt.total);
                    console.log("正在提交..." + percentComplete.toString() + '%');        //在控制台打印上传进度  
                }
            }, false);

            return xhr;
        }

    });
});

功能函数: getRectCanvas:用于绘制矩形Canvas,
convertBase64UrlToBlob:将以base64的图片url数据转换为Blob

//绘制矩形canvas
function getRectCanvas(sourceCanvas) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var width = sourceCanvas.width;
    var height = sourceCanvas.height;

    canvas.width = width;
    canvas.height = height;

    context.imageSmoothingEnabled = true;
    context.drawImage(sourceCanvas, 0, 0, width, height);
    context.globalCompositeOperation = 'destination-in';
    context.beginPath();
    context.rect(0, 0, width, height);
    context.fill();

    return canvas;
}

/**  
* 将以base64的图片url数据转换为Blob  
* @param urlData  
* 用url方式表示的base64图片数据  
*/
function convertBase64UrlToBlob(urlData) {
    var bytes = window.atob(urlData.split(',')[1]);       //去掉url的头,并转换为byte 
    //处理异常,将ascii码小于0的转换为大于0  
    var ab = new ArrayBuffer(bytes.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], { type: 'image/png' });
}

后端php接收裁剪图片数据

接收数据分两种情况:

  1. 接收Blob文件数据
$filename = $_FILES['filename'];
move_uploaded_file($filename['tmp_name'],'./'.$filename['name'].'png');
exit(json_encode(['status'=>1,'msg'=>'头像上传成功']));
  1. 接收base64文件数据
header('Content-type:text/html;charset=utf-8');
$base64_image_content = $_FILES['filename'];

//保存base64字符串为图片
//匹配出图片的格式
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
    $type = $result[2];
    $new_file = "./test.{$type}";
    if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) {
        echo '新文件保存成功:',
        $new_file;
    }
}

好了大告成功,以上就是h5利用cropper.js实现图片裁剪实现过程

demo和源码

demo: https://awei922.github.io/html/cropperjs-demo/index.html
源码:https://github.com/awei922/html/tree/master/swiper-demo

爱生活,爱技术

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注