思路:
talk is cheap ,let s see the code
1. FileReader获取图片的base64编码信息
$(document).on("change", "#upload-photo-pic", function (e) {
var file = this.files[0];
var fileReader=new FileReader();
//将文件以Data URL形式读入页面
fileReader.readAsDataURL(file);
fileReader.onload = function(e) {
var imageUrl=e.target.result;
// 借用canvas对base64图片进行压缩
canvasPress(imageUrl);
}
}
2.用canvas对图片进行压缩处理(包括压缩,旋转)
用canvas对图片进行处理前,先要通过以下三个步骤读图进canvas
上传图片太大了,要压缩,当然压缩的不是画质,而是照片的宽度(现在用单反或手机拍的,大则10几M,宽度7000px左右),我这边根据我的实际使用场景,如果图片宽度大于1200px,则统一把图片压缩成宽为1200px的图,缩放后1200*1800的图片,大小为2.8M左右。具体操作:
if(image.width>maxWidth){
image.height*=maxWidth/image.width;
image.width=maxWidth;
}
调整画布大小
canvas.width = image.height;
canvas.height = image.width;
本以为压缩下就万事大吉了,但是,并没有(要解决一个倒图问题):用iphone拍照的时候,你可能横着拍,也可能竖着拍,还可能倒着拍,不同的拍照方式照片的exif信息会记录不同的 Orientation,所以要把Orientation这个值取到(exif图片信息读取https://github.com/exif-js/exif-js/),然后根据这个值去旋转图片(旋转https://imququ.com/post/how-to-auto-rotate-photo-in-js.html)。 (在android手机拍的照片在测试中没有出现以上的倒图问题)。
canvas旋转也要稍微注意下,它并不是给他一个参数,说转多少就多少,拿到图片你就可以直接用,我用 rotate进行旋转,如 ctx.rotate(90Math.PI/180),由于坐标系也发生旋转,所以在画图的时候,**\y***相对来说要有-height的偏移,如
ctx.drawImage(image, 0, -image.height, image.width, image.height);
function canvasPress(imgurl){
// 如果图片宽度超过maxWidth,则宽度缩放至maxWidth
var maxWidth=1200;
var image = new Image();
image.onload = function(){
var canvas=document.getElementById("canvas-press");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 缩放
if(image.width>maxWidth){
image.height*=maxWidth/image.width;
image.width=maxWidth;
}
EXIF.getData(this, function(){
var orientation=EXIF.getTag(this, 'Orientation');
switch(orientation){
case 6://需要顺时针(向左)90度旋转
// 重置canvas宽高
canvas.width = image.height;
canvas.height = image.width;
ctx.rotate(90*Math.PI/180);
// 由于坐标系也发生旋转,所以是下面这样写的
ctx.drawImage(image, 0, -image.height, image.width, image.height);
break;
case 8://需要逆时针(向右)90度旋转
// 重置canvas宽高
canvas.width = image.height;
canvas.height = image.width;
ctx.rotate(-90*Math.PI/180);
// 由于坐标系也发生旋转,所以是下面这样写的
ctx.drawImage(image, -image.width,0, image.width, image.height);
break;
case 3:
// 重置canvas宽高
canvas.width = image.width;
canvas.height = image.height;
ctx.rotate(180*Math.PI/180);
// 由于坐标系也发生旋转,所以是下面这样写的
ctx.drawImage(image, -image.width, -image.height, image.width, image.height);
break;
default:
console.log('默认');
// 重置canvas宽高
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
break;
}
//接下去调用截图插件
setCroperInfo(canvas.toDataURL());
});
}
image.src = imgurl;
}
3.把用canvas api toDataURL
canvas.toDataURL()就可以直接拿到处理完毕的base64编码图片啦,然后你就可以按照自己想要的方式继续对图片进行处理了。
我在我的使用场景中,之后又调用了cropper对图片进行裁剪,然后传给后端进行保存。