这几天项目,遇到上传证件照的环节,所以需要实现手机相册或照相预览图片及压缩图片;
总体思路是:
1、FileReader.readAsDataURL将上传的图片文件转为Base64格式
2、将img绘制到canvas上,canvas.toDataURL压缩图片
3、new Blob将压缩后的Base64转为Blob格式
4、FormData.append将图片文件数据存入formdata
var upAvatarInput = document.getElementById('up-avatar-input'),
avatarImg = document.getElementsByClassName('avatar')[0] ;
// 图片预览
var file;
var MAX_IMG_SIZE=3*1024*1024;
// upAvatarInput为input file 原生元素
upAvatarInput.onchange = function (ev) {
var files = this.files;
file= files[0];
var reader;
// 接受 jpeg, jpg, png 类型的图片
if (!/\/(?:jpeg|jpg|png)/i.test(file.type)) {
alert('抱歉,暂时只支持jpeg, jpg, png格式的图片。')
return
}
if(typeof (FileReader) === 'undefined'){
alert('抱歉,您的浏览器不支持FileReader功能,请更换浏览器')
}else {
reader = new FileReader();
reader.onload = function (e) {
var result = this.result;
// 获取文件大小 单位为bit
var imgSize=e.total;
avatarImg.src = result;
// 清空图片上传框的值
upAvatarInput.value = '';
// 定义 已经被压缩 变量 否则进入死循环
var hasCompressed=false;
avatarImg.onload=function () {
// 获取图片的宽度 并修改‘点击上传证件照’的宽度
setUpImgWidth()
// 压缩图片
if (hasCompressed){
return
}
judgeCompress(avatarImg,imgSize);
hasCompressed=true;
}
};
reader.readAsDataURL(file); // 将上传的文件图片转为Base64
}
};
// 判断及压缩
function judgeCompress(img,imgSize) {
if (imgSize>MAX_IMG_SIZE){
try {
img.src = compressImg(img);
}catch (err){
alert('抱歉,执行compressImg函数出错'+err)
}
//去掉url的头,并转换为byte
var bytes = window.atob(img.src.split(',')[1]);
//处理异常,将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);
}
// file = new Blob( [ab] , {type : 'image/jpeg'});
file = new Blob( [ia] , {type : 'image/jpeg'});
file.name = '上传图片.jpeg';
alert('图片大于8M,已经进行压缩处理')
return img;
}else {
return img
}
}
// 压缩图片
function compressImg(image) {
console.log('compress');
console.log(image)
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d');
var imageLength = image.src.length;
var width = image.width;
var height = image.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(image, 0, 0, width, height);
//压缩操作
var quality = 1;//图片质量 范围:0<quality<=1 根据实际需求调正
var imageData = canvas.toDataURL("image/jpeg", quality); // 把canvas画布转换成img图像 将图片转换成base64格式 另外: png 不支持quality参数 所以写死image/jpeg
console.log("压缩前:" + imageLength);
console.log("压缩后:" + imageData.length);
console.log("压缩率:" + ~~(100 * (imageLength - imageData.length) / imageLength) + "%");
return imageData;
}
// 传递给后端
var formData = new FormData();
formData.append('file', file, file.name || '上传图片.jpeg'); // formData.append 第三个参数一定要传递,如果不传就是filename=blob,后端校验文件名可能过不去
// 略。。。。。 在ajax里记得加请求头
headers: {
'Content-Type': 'multipart/form-data', // 以表单传数据的格式来传递fromdata
},
// ajax 可能contentType和processData需要传false
参考资料:
1、 前端js压缩图片并上传
2、js上传图片处理:压缩,旋转校正图片
扩展资料:
1、 移动端上传图片翻转的解决方案