天天看点

移动端H5上传图片的一些坑

移动端做图片上传功能,大体上要经历以下几个步骤。

  • 利用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;
     }
}      

这样就完成了图片的旋转。

继续阅读