使用EXIF和BinaryFile会出错

时间:2014-06-03 08:20:33

标签: javascript filereader exif

我尝试在移动网页浏览器中使用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;
    }
};

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

如何获得此数组缓冲区?

我使用EXIF.js和BinaryFile.js

2 个答案:

答案 0 :(得分:11)

您需要将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;
}

您不需要BinaryFile

var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(this.result));

这假设您使用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);
  });
}

答案 1 :(得分:-1)

@ chings228你必须将base64数据传递给base64ToArrayBuffer,而不是blob数据。

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;
}

var b64 = "data:image/jpeg;base64,"+$parameters.image;
var exif = EXIF.readFromBinaryFile(base64ToArrayBuffer(b64));
alert(exif.Orientation);