Ortal Blumenfeld Lagziel
Ortal Blumenfeld Lagziel

Reputation: 2555

Using EXIF and BinaryFile get an error

I'm trying to draw photo with correct orientation in canvas after capture photo by using input[type='file'] in mobile web browser for that I'm using:

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

But I get: TypeError: First argument to DataView constructor must be an ArrayBuffer?

How can I get this array buffer?

I'm using EXIF.js and BinaryFile.js

Upvotes: 3

Views: 9412

Answers (2)

nanobar
nanobar

Reputation: 66455

You need to convert the base64 string to an ArrayBuffer for ExifJs:

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

You don't need BinaryFile:

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

This assumes you are using FileReader with readAsDataURL to get this.result.

A better approach would be to read the file as an array buffer to begin with and not convert it to base64 and then back again using FileReader.readAsArrayBuffer(). Something along the lines of this (pseudocode):

// `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);
  });
}

Upvotes: 12

Harlin
Harlin

Reputation: 1

@chings228 you must pass base64 data to base64ToArrayBuffer, not blob data.

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

Upvotes: -1

Related Questions