跳到主要内容

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

· 阅读需 6 分钟
lzw.

最近为了实现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://lzwdot.github.io/html/cropperjs-demo/index.html
源码:https://github.com/lzwdot/html/tree/master/swiper-demo