天天看點

移動端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;
     }
}      

這樣就完成了圖檔的旋轉。

繼續閱讀