Mattew Skin
Mattew Skin

Reputation: 33

Retrieve binary data / EXIF from image on the page

I need to access EXIF data in images already loaded on page. Say, from browser extension. AFAIU, there are some javascript approaches to accomplish the task:

First two approaches may either deal with local files or they require to perform an additional (superfluous in this case) request to the server to retrieve binary data. The latter likely works:

var canvas = document.createElement("canvas");
canvas.width = oImg.width;
canvas.height = oImg.height;

// Copy the image contents to the canvas
var ctx = canvas.getContext("2d");
ctx.drawImage(oImg, 0, 0);

// Get the data-URL formatted image
var dataURL = window.atob(canvas.toDataURL("image/jpeg", 1.0).split(',')[1]);

but the resulting binary object does not contain EXIF data (0xE1 marker,) it seems that once drawn on canvas, it yields the JFIF (0xE0) marker instead.

So, my question is: is it possible to get an access to binary data of already loaded image on the page?

Please note: there are similar questions already on SO, but none answers the question how not to reload an image and get an access to EXIF data.

I understand that I could save an image locally into, say, LocalStorage and then use the library mentioned above but it also looks like an overkill.

Upvotes: 3

Views: 2234

Answers (1)

user1693593
user1693593

Reputation:

Is it possible to get an access to binary data of already loaded image on the page?

No, this is unfortunately not possible, not from the raw binary file data used for the image. The original binary data is discarded after the image has been processed.

The image loading process is a completely separate process and does not involve canvas at all - canvas is innocent here! :-)

A browser loads an image in roughly the following way, which all happens internally with no access from JavaScript or DOM (not necessarily in this order for all stages):

  • Connects to server
  • Loads data to determine file type
  • If a supported file type, loads all data
  • Extracts ICC and gamma definitions if supported
  • Extract EXIF orientation/rotation if present
  • Decompresses/decodes the file into a bitmap
  • Applies gamma and ICC correction if available and supported
  • Updates the Image object with internal reference to bitmap
  • Broadcasts an load event
  • Invokes onload call in any

When you receive the Image object everything has been prepared and set - the rest of the file and the information extracted from it is discarded, incl. EXIF data (with the exception from EXIF orientation in browsers which support it, however, for internal use only, not available to be read from JavaScript and only used for DOM - though as it could break intended layout it is typically ignored). I believe most browsers are able to read this flag but AFAIK only Safari mobile actually uses it (I could be wrong here, but it does not change the essence of the answer).

There is only a bitmap left with RGBA information. You can now insert that into DOM or draw it onto a canvas, but the meta information is already stripped before doing this. When you extract a data-uri from canvas (as png or jpeg, doesn't really matter) the extraction is based solely on the bitmap of the canvas, not the original image used on it (images are just one source of graphic anyways, in addition to video and paths).

As there is no official API at the moment to access EXIF data from the Image object, the only way is to get the EXIF data read is to read the image as a binary stream into a binary buffer and extract the data manually and low-level using JavaScript. This is the reason why the libraries you list has to do it this way. The cache may come to rescue though.

This is probably not what you hoped for, but we are left with no other option that this, -or- doing it on server side (at for example upload time). You could then provide a mechanism to load cached EXIF data as a JSON object, or something similar.

Upvotes: 3

Related Questions