Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 593
Ortal Blumenfeld Lagziel Avatar asked Mar 21 '26 09:03

Ortal Blumenfeld Lagziel


1 Answers

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);
  });
}
like image 154
Dominic Avatar answered Mar 23 '26 00:03

Dominic