使用EXIF和BinaryFile会出错

Ort*_*iel 3 javascript exif filereader

我正在尝试使用input[type='file']移动网络浏览器在拍摄照片后在画布中使用正确的方向绘制照片我正在使用:

fileReader.onloadend = function() {
    var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));

    switch(exif.Orientation){
       case 8:
           ctx.rotate(90*Math.PI/180);
           break;
       case 3:
           ctx.rotate(180*Math.PI/180);
           break;
       case 6:
           ctx.rotate(-90*Math.PI/180);
           break;
    }
};
Run Code Online (Sandbox Code Playgroud)

但我明白了:TypeError: First argument to DataView constructor must be an ArrayBuffer

我怎样才能得到这个数组缓冲区?

我正在使用EXIF.js和BinaryFile.js

Dom*_*nic 12

您需要将base64字符串转换为ExifJs 的ArrayBuffer:

function base64ToArrayBuffer (base64) {
    base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
    var binaryString = atob(base64);
    var len = binaryString.length;
    var bytes = new Uint8Array(len);
    for (var i = 0; i < len; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes.buffer;
}
Run Code Online (Sandbox Code Playgroud)

你不需要BinaryFile:

var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(this.result));
Run Code Online (Sandbox Code Playgroud)

这是假设你正在使用FileReaderreadAsDataURL获得this.result.

更好的方法是将文件作为数组缓冲区读取,而不是将其转换为base64,然后再使用FileReader.readAsArrayBuffer()将其转换回来.有点像这样的(伪代码):

// `file` = files[0] from input change event
function getFileArrayBuffer(file) {
  return new Promise(function (resolve, reject) {
    var reader = new FileReader();
    reader.onload = function() {
      resolve(new Uint8Array(reader.result));
    }
    reader.readAsArrayBuffer(file);
  });
}
Run Code Online (Sandbox Code Playgroud)