移动端做图片上传功能,大体上要经历以下几个步骤。
- 利用fileReader,读取blob对象或者file对象,将图片转为data uri的形式
- 利用canvas,在页面上新建一个画布,利用canvas提供的api,将图片画入到这个画布中
- 利用canvas.toDataUrl(),进行图片的压缩,得到图片的data url值
- 上传文件
步骤一当中,在进行图片压缩的时候,我们要先进性判断文件的大小,如果图片大小是小于200KB的时候,我们是不需要进行压缩的,直接对图片进行上传。如果图片是大于200KB的时候,则要先进行压缩再上传。
相关api兼容性可以查询 https://caniuse.com/
步骤一: 读取文件
var fileChooser = document.getElementById('choose');
var maxSize = 200 * 1024;
fileChooser.onchange = function () {
var file = this.files[0];
var reader = new FileReader();
reader.onload = function () {
var result = this.result;
var img = new Image();
img.src = result;
if (result.length < maxSize) {
imgUpload(result);
}
else {
var data = compress(img);
imgUpload(data);
}
}
reader.readAsDataURL(file);
}
步骤二:新建canvas
var canvas = document.createElement('canvas');
步骤三:利用canvas进行压缩
function compress(img) {
canvas.width = img.width;
canvas.height = img.height;
var data = canvas.toDataURL('image/jpeg', 0.2); // 0.2为图片的质量选项
return data;
}
在利用canvas进行绘图的过程中,ios图片上传过程中,会存在这样的情况,当手机是自拍的时候拍出来的照片是反的。这个时候如果想纠正图片自动旋转的情况,将图片转为二进制数据,使用(binaryajax.js),方便获取图片的exif信息,通过获取exif的信息来确定图片旋转的角度(使用了exif.js),然后再进行图片的相应的旋转处理。
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
EXIF.getData(file, function () {
orientation = EXIF.getTag(this, 'Orientation');
console.log(orientation); // 只有图片是旋转状态的才可以拿到值,不然就是undefined
alert(orientation);
})
根据判断orientation的角度值来判断是否要旋转,
// html
<input type="file" id="choose" accept="image/*">
<canvas id="canvas"></canvas>
// javascript
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
function compress(img) {
if (orientation === 6) { // 左右相反
console.log(img)
document.body.appendChild(img);
canvas.width = img.width;
canvas.height = img.height;
context.rotate(180*Math.PI/180); // 进行旋转
context.drawImage(img, 0, 0, -img.width, -img.height);
var data = canvas.toDataURL('image/jpeg', 0.2);
return data;
}
}
这样就完成了图片的旋转。
我们图片上传采用base64编码进行上传。这样比较简单,云端支持也容易。
至此我们就解决了图片上传的问题。