在线图片裁剪,关于使用cropperjs踩过的坑
最近在做一个项目,其中包括了一个图片在线裁剪功能,于是找到了cropperjs,cropperjs的裁剪功能丰富,满足了各种需求,预览链接:cropperjs预览
裁剪图片的两种思路:
1.在前端裁剪,通过html5的HTMLCanvasElement.toBlob
方法,把裁剪后的图片通过表单方式用ajax提交给后台,或者使用HTMLCanvasElement.toDataURL
把图片转换为base64提交到后台。
2.在后台裁剪,在前端裁剪后把裁剪的坐标和裁剪之前的原图发送到后台,让后台执行裁剪,把裁剪后的图片返回
以上两种方法使用cropperjs都是支持的,自己选择了第一种方案,减轻后台工作。
第一次使用HTMLCanvasElement.toDataURL
以base64的方式把数据提交到后台,结果发现base64的串实在是太长了,和后台通讯非常耗时。
放弃base64
然后使用HTMLCanvasElement.toBlob
方法,构造了一个表单,提交给后台,发现报了413的错误
413是Nginx返回的,然后查了一下Nginx的配置:
http {
include mime.types;
default_type application/octet-stream;
client_max_body_size 10M;
}
最大上传的10M,看了一下上传的原图才1.75M,这不应该有413
看了看http请求,发现图片大小17M多,比裁剪前的原图还大,图片格式是png
翻了一下官方的文档,HTMLCanvasElement.toBlob()
有三个参数,第一个是回调函数,第二个是图片的格式,默认是png,第三个是图片的质量,到这里,明白了为什么产生413,因为裁剪前的原图是jpg,裁剪后变成了png,而同样一张图片,png比jpg要大得多,所以才会出现裁剪后比原图大的情况
到这里就好办了,把第二个参数传进去,图片格式为image/jpeg,图片裁剪上传成功
在后来,发现360浏览器竟然不支持toBlob :
cropper.getCroppedCanvas().toBlob is not a function
在GitHub上面搜索了相关问题,最终发现一个兼容方案:https://github.com/blueimp/JavaScript-Canvas-to-Blob,具体实现看作者的源码,一百多行。
到这里,在线图片裁剪,算是实现了,贴一下效果图和源码:
//解决某些浏览器不支持canvas的toBlob方法问题
var blob = require("./../biz_common/blob");
cropper.getCroppedCanvas().toBlob(function (blob) {
var formData = new FormData();
formData.append("croppedImage" , blob);
$.ajax("/modupload",{
method: "POST",
beforeSend: function () {
loader.removeClass("hide");
},
data: formData,
processData: false,
contentType: false,
success: function (data) {
if (data.success) {
console.log("upload success");
}
},
error: function () {
console.log("upload error");
}
});
},"image/jpeg");