Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for images with src of type "Data URI" (Base64) or "Object URL" (Blob). #6

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
115 changes: 85 additions & 30 deletions exif.js
Expand Up @@ -57,7 +57,7 @@ var EXIF = (function() {
0x9214 : "SubjectArea", // Location and area of main subject
0x920A : "FocalLength", // Focal length of the lens in mm
0xA20B : "FlashEnergy", // Strobe energy in BCPS
0xA20C : "SpatialFrequencyResponse", //
0xA20C : "SpatialFrequencyResponse", //
0xA20E : "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit
0xA20F : "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit
0xA210 : "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
Expand All @@ -77,7 +77,7 @@ var EXIF = (function() {
0xA408 : "Contrast", // Direction of contrast processing applied by camera
0xA409 : "Saturation", // Direction of saturation processing applied by camera
0xA40A : "Sharpness", // Direction of sharpness processing applied by camera
0xA40B : "DeviceSettingDescription", //
0xA40B : "DeviceSettingDescription", //
0xA40C : "SubjectDistanceRange", // Distance to subject

// other tags
Expand Down Expand Up @@ -294,17 +294,48 @@ var EXIF = (function() {
};

function addEvent(element, event, handler) {
if (element.addEventListener) {
element.addEventListener(event, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + event, handler);
if (element.addEventListener) {
element.addEventListener(event, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + event, handler);
}
}

function imageHasData(img) {
return !!(img.exifdata);
}

function base64ToBlob(base64, contentType) {
contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');

var binary = atob(base64);
var len = binary.length;
var buffer = new ArrayBuffer(len);
var view = new Uint8Array(buffer);

for (var i = 0; i < len; i++) {
view[i] = binary.charCodeAt(i);
}
var blob = new Blob([view], {type: contentType});

return blob;
}

function objectURLToBlob (object_url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', object_url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
var blob;
if (this.status === 200) {
blob = this.response;
}
callback(blob);
};
xhr.send();
}

function getImageData(img, callback) {
function handleBinaryFile(binFile) {
var data = findEXIFinJPEG(binFile);
Expand All @@ -315,10 +346,34 @@ var EXIF = (function() {
}

if (img instanceof Image) {
BinaryAjax(img.src, function(http) {
handleBinaryFile(http.binaryResponse);
});
} else if (window.FileReader && img instanceof window.File) {
if (/^data\:/i.test(img.src)) { // Data URI
var fileReader = new FileReader();

fileReader.onload = function(e) {
handleBinaryFile(new BinaryFile(e.target.result));
};

var blob = base64ToBlob(img.src);

fileReader.readAsBinaryString(blob);

} else if (/^blob\:/i.test(img.src)) { // Object URL
var fileReader = new FileReader();

fileReader.onload = function(e) {
handleBinaryFile(new BinaryFile(e.target.result));
};

objectURLToBlob(img.src, function (blob) {
fileReader.readAsBinaryString(blob);
});

} else { // HTTP URL
BinaryAjax(img.src, function(http) {
handleBinaryFile(http.binaryResponse);
});
}
} else if (img instanceof Blob || (window.FileReader && img instanceof window.File)) {
var fileReader = new FileReader();

fileReader.onload = function(e) {
Expand Down Expand Up @@ -346,20 +401,20 @@ var EXIF = (function() {

marker = file.getByteAt(offset+1);

// we could implement handling for other markers here,
// we could implement handling for other markers here,
// but we're only looking for 0xFFE1 for EXIF data

if (marker == 22400) {
if (debug) console.log("Found 0xFFE1 marker");

return readEXIFData(file, offset + 4, file.getShortAt(offset+2, true)-2);

// offset += 2 + file.getShortAt(offset+2, true);

} else if (marker == 225) {
// 0xE1 = Application-specific 1 (for EXIF)
if (debug) console.log("Found 0xFFE1 marker");

return readEXIFData(file, offset + 4, file.getShortAt(offset+2, true)-2);

} else {
Expand All @@ -373,10 +428,10 @@ var EXIF = (function() {

function readTags(file, tiffStart, dirStart, strings, bigEnd) {
var entries = file.getShortAt(dirStart, bigEnd),
tags = {},
tags = {},
entryOffset, tag,
i;

for (i=0;i<entries;i++) {
entryOffset = dirStart + i*12 + 2;
tag = strings[file.getShortAt(entryOffset, bigEnd)];
Expand Down Expand Up @@ -526,23 +581,23 @@ var EXIF = (function() {
case "SceneCaptureType" :
case "SceneType" :
case "CustomRendered" :
case "WhiteBalance" :
case "GainControl" :
case "WhiteBalance" :
case "GainControl" :
case "Contrast" :
case "Saturation" :
case "Sharpness" :
case "Sharpness" :
case "SubjectDistanceRange" :
case "FileSource" :
exifData[tag] = StringValues[tag][exifData[tag]];
break;

case "ExifVersion" :
case "FlashpixVersion" :
exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);
break;
case "ComponentsConfiguration" :
exifData[tag] =

case "ComponentsConfiguration" :
exifData[tag] =
StringValues.Components[exifData[tag][0]]
+ StringValues.Components[exifData[tag][1]]
+ StringValues.Components[exifData[tag][2]]
Expand All @@ -557,10 +612,10 @@ var EXIF = (function() {
gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);
for (tag in gpsData) {
switch (tag) {
case "GPSVersionID" :
gpsData[tag] = gpsData[tag][0]
+ "." + gpsData[tag][1]
+ "." + gpsData[tag][2]
case "GPSVersionID" :
gpsData[tag] = gpsData[tag][0]
+ "." + gpsData[tag][1]
+ "." + gpsData[tag][2]
+ "." + gpsData[tag][3];
break;
}
Expand Down Expand Up @@ -591,7 +646,7 @@ var EXIF = (function() {

function getAllTags(img) {
if (!imageHasData(img)) return {};
var a,
var a,
data = img.exifdata,
tags = {};
for (a in data) {
Expand Down Expand Up @@ -627,14 +682,14 @@ var EXIF = (function() {
return findEXIFinJPEG(file);
}


return {
readFromBinaryFile : readFromBinaryFile,
pretty : pretty,
getTag : getTag,
getAllTags : getAllTags,
getData : getData,

Tags : ExifTags,
TiffTags : TiffTags,
GPSTags : GPSTags,
Expand Down