Questions:近期需要做一个需求,关于前端获取图片后压缩,再上传给后台服务器或者上传至oss后将路径传给后台服务器,压缩的时候发现在ios10及以下的系统是无效的,经查证,这是由于使用canvas的 ()
方法创造blob对象的时候,ios10及以下系统无法调用。
Answer:
1. 实现前端压缩图片并上传
(1)HTML:图片预览盒子&input上传控件
<div >
<!-- 展示预览图片 -->
<!-- <div class="img_show"></div> -->
<!-- 图片上传 -->
<div class="img_uploader">
<input type="file" name="imgs" accept="image/*">
</div>
</div>
(2)图片上传及压缩
// 表单上传的formdata对象
var fd = new FormData();
// 用于压缩图片的canvas
var canvas = ('canvas');
var ctx = ('2d');
var img = new Image();
var file = null; // 用户上传的图片对象
/* 点击input上传图片 */
$("#fileupload").on('change', function (e) {
file = [0];
// 图片预览,加载base64图片
var reader = new FileReader();
= (function (file) {
return function (e) {
var datainfo = ;
= datainfo;
var html = '<div class="img_show" style="background-image:url('+ datainfo +')"></div>'
$("#uploader").prepend(html);
if ($("#uploader .img_showCurrent").length >= 2) {
$("#fileInput").hide();
}
};
})([0]);
([0]);
// base64地址图片加载完毕后,绘制canvas压缩图片
= function () {
// 图片原始尺寸
var originWidth = ;
var originHeight = ;
// 最大尺寸限制
var maxWidth = 800, maxHeight = 800;
// 目标尺寸
var targetWidth = originWidth, targetHeight = originHeight;
// 图片尺寸超过400x400的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth;
targetHeight = (maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = (maxHeight * (originWidth / originHeight));
}
}
// canvas对图片进行缩放
= targetWidth;
= targetHeight;
// 清除画布
(0, 0, targetWidth, targetHeight);
// 图片压缩
(img, 0, 0, targetWidth, targetHeight);
// 当canvas对象的原型中没有toBlob方法的时候,手动添加该方法
if (!) {
(, 'toBlob', {
value: function (callback, type, quality) {
var binStr = atob( (type, quality).split(',')[1] ),
len = ,
arr = new Uint8Array(len);
for (var i=0; i<len; i++ ) {
arr[i] = (i);
}
callback( new Blob( [arr], {type: type || 'image/png'} ) );
}
});
}
// canvas转为blob并上传
(function (blob) {
('pic', blob)
}, ||'image/png');
};
})
(3)上传图片
("uid", uids);
$.ajax({
type: "post",
url: baseUrl + "xxxx/xxxxx",
data: fd,
dataType: "json",
processData: false, // processData和contentType需设置为false
contentType: false,
async: false,
success: function (res) {
// ... ...
}
})
2. 兼容ios10系统
// 当canvas对象的原型中没有toBlob方法的时候,手动添加该方法
if (!) {
(, 'toBlob', {
value: function (callback, type, quality) {
var binStr = atob( (type, quality).split(',')[1] ),
len = ,
arr = new Uint8Array(len);
for (var i=0; i<len; i++ ) {
arr[i] = (i);
}
callback( new Blob( [arr], {type: type || 'image/png'} ) );
}
});
}