exif-js / exif-js Goto Github PK
View Code? Open in Web Editor NEWJavaScript library for reading EXIF image metadata
License: MIT License
JavaScript library for reading EXIF image metadata
License: MIT License
I am using the exif.js script to get exif data from images. When I load the same image on my development server, the data returned is different than when I load it on my production server. Below is the returned data:
Production Server:
{"FILE":{"FileName":"phpGiolhf","FileDateTime":1489687579,"FileSize":5572566,"FileType":2,"MimeType":"image/jpeg","SectionsFound":"ANY_TAG, IFD0, EXIF"},"COMPUTED":{"html":"width=\"5312\" height=\"2988\"","Height":2988,"Width":5312,"IsColor":1,"ByteOrderMotorola":0,"ApertureFNumber":"f/1.9"},"IFD0":{"ImageWidth":5312,"ImageLength":2988,"Make":"samsung","Model":"SAMSUNG-SM-G920A","Orientation":6,"XResolution":"72/1","YResolution":"72/1","ResolutionUnit":2,"Software":"G920AUCS5DPK5","DateTime":"2017:03:15 21:40:20","YCbCrPositioning":1},"EXIF":{"ExposureTime":"1/17","FNumber":"19/10","ExposureProgram":2,"ISOSpeedRatings":1250,"ExifVersion":"0220","DateTimeOriginal":"2017:03:15 21:40:20","DateTimeDigitized":"2017:03:15 21:40:20","ShutterSpeedValue":"410/100","ApertureValue":"185/100","BrightnessValue":"-256/100","ExposureBiasValue":"0/10","MaxApertureValue":"185/100","MeteringMode":2,"Flash":0,"FocalLength":"430/100"}}
Development:
{"FILE":{"FileName":"phpEVKnpq","FileDateTime":1489687140,"FileSize":5572566,"FileType":2,"MimeType":"image/jpeg","SectionsFound":"ANY_TAG, IFD0, THUMBNAIL, EXIF, GPS"},"COMPUTED":{"html":"width=\"5312\" height=\"2988\"","Height":2988,"Width":5312,"IsColor":1,"ByteOrderMotorola":0,"ApertureFNumber":"f/1.9","UserComment":null,"UserCommentEncoding":"UNDEFINED","Thumbnail.FileType":2,"Thumbnail.MimeType":"image/jpeg","Thumbnail.Height":288,"Thumbnail.Width":512},"IFD0":{"ImageWidth":5312,"ImageLength":2988,"Make":"samsung","Model":"SAMSUNG-SM-G920A","Orientation":6,"XResolution":"72/1","YResolution":"72/1","ResolutionUnit":2,"Software":"G920AUCS5DPK5","DateTime":"2017:03:15 21:40:20","YCbCrPositioning":1,"Exif_IFD_Pointer":246,"GPS_IFD_Pointer":818},"THUMBNAIL":{"ImageWidth":512,"ImageLength":288,"Compression":6,"Orientation":6,"XResolution":"72/1","YResolution":"72/1","ResolutionUnit":2,"JPEGInterchangeFormat":1154,"JPEGInterchangeFormatLength":7398},"EXIF":{"ExposureTime":"1/17","FNumber":"19/10","ExposureProgram":2,"ISOSpeedRatings":1250,"ExifVersion":"0220","DateTimeOriginal":"2017:03:15 21:40:20","DateTimeDigitized":"2017:03:15 21:40:20","ShutterSpeedValue":"410/100","ApertureValue":"185/100","BrightnessValue":"-256/100","ExposureBiasValue":"0/10","MaxApertureValue":"185/100","MeteringMode":2,"Flash":0,"FocalLength":"430/100","MakerNote":"\u0007","UserComment":"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","FlashPixVersion":"0100","ColorSpace":1,"ExifImageWidth":5312,"ExifImageLength":2988,"ExposureMode":0,"WhiteBalance":0,"FocalLengthIn35mmFilm":28,"SceneCaptureType":0,"ImageUniqueID":"A16LSIA00VM A16LSJG01SM\n"},"GPS":{"GPSVersion":"\u0002\u0002\u0000\u0000","GPSLatitudeRef":"N","GPSLatitude":["32/1","14/1","43/1"],"GPSLongitudeRef":"W","GPSLongitude":["89/1","57/1","33/1"],"GPSAltitudeRef":"\u0001","GPSAltitude":"0/1","GPSTimeStamp":["2/1","40/1","16/1"],"GPSDateStamp":"2017:03:16"}}
I'd like to use the library for an enterprise project I am working on but I am getting the following error in BinaryAjax.js in IE9 (in IE9 browser/document modes).
SCRIPT258: Could not complete the operation due to error 80020102.
binaryajax.js?130612120748, line 42 character 7
I have tried to use exif-js with Cordova, however, the only tags I get from an image taken with an iPhone by calling EXIF.getAllTags(img) are:
{Orientation: 6, ExifIFDPointer: 38, ColorSpace: 1, PixelXDimension: 3264, PixelYDimension: 2448}
Is there no support for mobile?
While PNG does not support EXIF as-is, it seems that some tools including ImageMagick and ExifTool store EXIF with 'Raw profile type APP1' or 'Raw profile type exif' tag IDs. Can we support this?
Works fine in FF/Win8, but on the iPad I only get these 5 Exif tags:
Orientation
ExifIFDPointer
ColorSpace
PixelXDimension
PixelYDimension
Is there anything you are doing in binaryajax.js that is not strictly HTML5?
Paste exif.js to http://jshint.com/ and see how many undefined variables are there.
Because of undefined variables browserify can break projects that use exif-js.
I am trying to get timezone for the time when the image was taken.
Date/Time Original doesn't contain any timezone information
GPS Date/Time contains timezone information
However, exif-js doesn't seem to read GPS Date/Time.
Is there a reason why?
exif.js:594 Uncaught RangeError: Offset is outside the bounds of the DataView
If choosed image's dpi higher then 600,it will crash.
I currently add try catch to solve this issue.
But i wonder it's can be fix or maybe no one will choose 600dpi images?
Hi,
thanks for your useful library!
I've some photos with "Orientation: 8". By looking at them I get that i must "rotate 90° counterclockwise", but I'd love a reference with all the other possible values. Is it available somewhere?
Plus: I'd like to avoid if(orientation == 8)
in my client. Is there a constant so that I can use something among the lines of if(orientation == EXIF.ORIENTATION_90_CCW)
?
Saw the recent inclusion of IPTC methods in December. Wondering when the next official release will be to get these included?
Base64 Test
<script>
document.getElementById("base64test").onclick = function() {
var image = new Image();
image.onload = function() {
EXIF.getData(image, function() {
alert(EXIF.pretty(this));
});
};
image.src = "data:image/jpeg;base64,/9j/......"
}
</script>
I'm trying to run the following :
var exif = require('exif-js');
var fs = require('fs');
var imageBuffer = fs.readFileSync('hatching_orig.jpg');
exif.getData(imageBuffer, function() {
console.log(exif.pretty(imageBuffer));
});
in node v4.4.7
and getting the following error:
if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false;
^
ReferenceError: Image is not defined
I'm getting the gps latitude and longitude values wrong.. the placement of point is placed wrong.. did anybody solved this type of problem.Please suggest me.
Maybe some changes in the forked branches too?
exif.js文件
问题:严格模式下,代码抛异常。
引起异常的方法:
function getStringFromDB(buffer, start, length) {
var outstr = "";
for (n = start; n < start+length; n++) {
outstr += String.fromCharCode(buffer.getUint8(n));
}
return outstr;
}
此方法中变量n未定义,直接使用,打包构建时,在严格模式下会抛出异常。导致拍照上传工能无法使用。
修改建议:将n预先定义,如下:
function getStringFromDB(buffer, start, length) {
var outstr = "",n;
for (n = start; n < start+length; n++) {
outstr += String.fromCharCode(buffer.getUint8(n));
}
return outstr;
}
Hi @jseidelin , I wonder if you know how to strip off EXIF data from file using JS?
I'm building a client-side cropping solution. It reads file content from the FileReader API. And I base64 encode the file content to insert it as a src in an img tag. Than I'm using canvas to crop the image and it is here everything goes wrong. I can't crop with canvas, because canvas don't know what EXIF data is.
I've searched the whole Internet didn't find anything on how-to do it using Javascript
I'm basically having this issue: http://stackoverflow.com/questions/24010310/using-exif-and-binaryfile-get-an-error
readFromBinaryFile
eventually calls the DataView
constructor, passing in a BinaryFile
, but the constructor throws an error, because it expects an ArrayBuffer
.
The library assumes that if the first offset listed is not 0x00000008, then it's not valid Exif data:
if (file.getUint32(tiffOffset+4, !bigEnd) != 0x00000008) {
if (debug) console.log("Not valid TIFF data! (First offset not 8)", file.getUint16(tiffOffset+4, !bigEnd));
return false;
}
tags = readTags(file, tiffOffset, tiffOffset+8, TiffTags, bigEnd);
I have a file with "valid" Exif data (exiftool
returns all the info properly), but Exif.js is deciding it doesn't contain valid data. This file is straight off a Fuji FinePix XP10
For the file in question, the resulting offset is 0x00000D4C (3404) instead of 0x00000008, and examining the JPEG file in a Hex editor, the Exif data does indeed start at an offset of 3404.
If I change the code as follows (basically removing the check and just using whatever the file says the first offset is), my Exif data is properly read:
firstOffset = file.getUint32(tiffOffset+4, !bigEnd)
tags = readTags(file, tiffOffset, firstOffset, TiffTags, bigEnd);
I'm not familiar enough with the Exif protocol to know if it would be harmful to just blindly use the offset provided by the file instead of a forced requirement for the 0x00000008 offset?
The test of img instanceof Image does not work in Chrome. img instanceof HTMLImageElement should be added
When using this library in other instances, the library should register itself anonymously and therefore default to it's filename
The demo gives this error every time I click on a demo image. I am assuming the demo should show the exif on clicking the demo images. Not so likely to use this if the demo does not even function. Any ideas why?
Hello,
The new version of exif.js doesn't work, because EXIF.getData() returns always FALSE.
In EXIF.getData() the line
if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false;
was replace with this
if ((self.Image && img instanceof self.Image) || (self.HTMLImageElement && img instanceof self.HTMLImageElement) && !img.complete) return false;
I think brackets are missing
you wrote:
A or B and C
but I think it should be
( A or B ) and C
Thank
CachingFoX
Hi there.
When I try to get exif data for images on my subdomain I got:
XMLHttpRequest cannot load http://img.domain.com/o.jpg. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://domain.com' is therefore not allowed access.
Is there any way to get it fixed?
It could be my limited intelligence.
But I actually think there would be a lot of people who would prefer to have a little documentation, like some samples in the README.md
to get them going more quickly using this library.
Now you have to get it all from the code itself, which just takes more time.
This library looks great, but is obviously designed to work in browsers.
Could you add support to load an image from an uri (including a file uris crucially) for use in react-native that bypasses any code that invokes in-browser classes (like Image and HTMLImageElement)?
I am using a tool called phoshare to export iphoto images. It puts metadata in the keywords exif tag, which doesn't seem to be supported by exif-js. How do I add support for this one?
Hi, in the document, you said must wait till the img tag loaded then get data, but actually, when I do this, I found after img tag loaded, the getData function downloads the image again, with an xhr request. So when using a onLoad() function after img tag loaded, this getData function will download the image again to fetch the exif data, either this should not happen or the documentation should be changed now.
I found the code, clearly this implies the img can be an object with a attribute src containing the url,
if (img.src) {
if (/^data\:/i.test(img.src)) { // Data URI
var arrayBuffer = base64ToArrayBuffer(img.src);
handleBinaryFile(arrayBuffer);
} else if (/^blob\:/i.test(img.src)) { // Object URL
var fileReader = new FileReader();
fileReader.onload = function(e) {
handleBinaryFile(e.target.result);
};
objectURLToBlob(img.src, function (blob) {
fileReader.readAsArrayBuffer(blob);
});
} else {
var http = new XMLHttpRequest();
http.onload = function() {
if (this.status == 200 || this.status === 0) {
handleBinaryFile(http.response);
} else {
throw "Could not load image";
}
http = null;
};
http.open("GET", img.src, true);
http.responseType = "arraybuffer";
http.send(null);
}
...
Hello.
My final goal is to find out the serial number of the camera used to take a picture.
It's either in the main exif datas :
0xc62f 50735 Image Exif.Image.CameraSerialNumber Ascii
0xa431 42033 Photo Exif.Photo.BodySerialNumber Ascii
or in the makernote value.
0x001d 29 Nikon3 Exif.Nikon3.SerialNumber Ascii Serial Number
I tried to add the 2 first to the list of tags, without success.
I tried also to read the makernote value, but it's an array with thousands of values, where I can't find my serial number(I know it's inside, I find it out with other tools).
Any idea on how to get the value ?
Best regards,
Pierre
bower info exif-js
bower exif-js#* not-cached git://github.com/jseidelin/exif-js.git#*
bower exif-js#* resolve git://github.com/jseidelin/exif-js.git#*
bower exif-js#* checkout master
bower exif-js#* resolved git://github.com/jseidelin/exif-js.git#fdf760cf40
{
name: 'exif-js',
homepage: 'https://github.com/jseidelin/exif-js',
authors: [
'Jacob Seidelin'
],
description: 'JavaScript library for reading EXIF image metadata',
main: 'exif.js',
keywords: [
'exif'
],
license: 'MIT',
ignore: [
'*/.',
'node_modules',
'bower_components',
'test',
'tests',
'spec',
'example'
]
}
Great tool. Could you please publish this to bower and npm?
Regards.
I put my image like this: src='img/gallery/photo1.jpg', and get a empty array. What´s wrong?
http://s3.amazonaws.com/grassrootsmapping/warpables/236383/RIMG0352.JPG and http://s3.amazonaws.com/grassrootsmapping/warpables/236381/RIMG0342.JPG have Orientation values of 3 and 8, respectively, which exif
and exifprobe
on Ubuntu correctly display:
$:~/Desktop/gps$ exifprobe RIMG0352.JPG | grep Orientation
@0x000003a=58 : <0x0112= 274> Orientation [3 =SHORT 1] = 3 = '0,0 is bottom right'
$:~/Desktop/gps$ exifprobe RIMG0342.JPG | grep Orientation
@0x000003a=58 : <0x0112= 274> Orientation [3 =SHORT 1] = 8 = '0,0 is left bottom'
But exif-js returns "1" for each. Is this an error in parsing hex data, or something?
latest version is way behind, and current published version was recently damaged by some kind of code deploy without version bump, and now contains the bug where getData fails to return.
Hi,
I came working with your code and I would like to make a recomendation for add support to read files from devices like phones where a XMLHttpRequest to read files will fail (application restrictions). Mostly is read images files that are locally and the URL starts with file:///
Here is the code (sorry I am new at GIT )
ADD to function (getImageData) this condition
else if (/^file:/i.test(img.src)) { // Object URL
var fileReader = new FileReader();
fileReader.onload = function(e) {
handleBinaryFile(e.target.result);
};
fileURLToBlob(img.src, function (File) {
fileReader.readAsArrayBuffer(File);
});
define the function fileURLToBlob
function fileURLToBlob(url, callback){
window.requestFileSystem(window.PERSISTENT, 99999, function(fs) {
var fileLocation = url.replace('file:/', '');
console.log(fileLocation);
fs.root.getFile(fileLocation, {create: false}, function(fileEntry) {
console.log(fileEntry);
var FileObject;
fileEntry.file(
function(fileObject){
console.log(fileObject);
callback(fileObject);
},
function(e){
console.log('Error getting the file object');
console.log(e);
}
);
},
function(e){
console.log('Error getting the file');
utils.errorHandlerFileSystem(e);
}
);
},
function(e){
console.log('Error request file system');
utils.errorHandlerFileSystem(e);
}
);
}
Thanks
On https://github.com/jseidelin/exif-js/blob/master/exif.js#L328 I get this error:
TypeError: DataView: expected ArrayBuffer, got Object
both in Firefox and Chrome.
With the previous version with readAsBinaryString
it's ok.
Does this version functions only on IE?
Thanks.
Since the last commit, getData function doesn't return any result.
It seems it's the first condition which isn't good.
Before
((img instanceof Image || img instanceof HTMLImageElement) && !img.complete)
Now
((self.Image && img instanceof self.Image) || (self.HTMLImageElement && img instanceof self.HTMLImageElement) && !img.complete)
A parenthesis problem with the img.complete boolean I think.
This condition may be :
(((self.Image && img instanceof self.Image) || (self.HTMLImageElement && img instanceof self.HTMLImageElement)) && !img.complete)
?
if ( typeof module != 'undefined' && module.exports ) {
module.exports = EXIF;
}
crash in function [objectURLToBlob]
not supporting blob as responseType on low version browser..eg android <=4.3..(http://caniuse.com/#search=XMLHttpRequest)
Im think you can use canvas2dataURL -> binary.
Below, I show my PHP code. You notice that I am setting IPCT values, but cannot read them back from your javascript. If your program not looking for those identifiers? How could I fix this?
`<?php
// iptc_make_tag() function by Thies C. Arntzen
function iptc_make_tag($rec, $data, $value)
{
$length = strlen($value);
$retval = chr(0x1C) . chr($rec) . chr($data);
if($length < 0x8000)
{
$retval .= chr($length >> 8) . chr($length & 0xFF);
}
else
{
$retval .= chr(0x80) .
chr(0x04) .
chr(($length >> 24) & 0xFF) .
chr(($length >> 16) & 0xFF) .
chr(($length >> 8) & 0xFF) .
chr($length & 0xFF);
}
return $retval . $value;
}
// Path to jpeg file
$path = './phplogo.jpg';
// Set the IPTC tags
$iptc = array(
'2#120' => 'Test image',
'2#116' => 'Copyright 2008-2009, The PHP Group'
);
// Convert the IPTC tags into binary code
$data = '';
foreach($iptc as $tag => $string)
{
$tag = substr($tag, 2);
$data .= iptc_make_tag(2, $tag, $string);
}
// Embed the IPTC data
$content = iptcembed($data, $path);
// Write the new image data out to the file.
$fp = fopen($path, "wb");
fwrite($fp, $content);
fclose($fp);
?>`
Given an image in the dom where we switch the src dynamically, it looks like EXIF will cache the tags and not reload it.
Line 420
// three parameters
return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);
function declaration:
// two parameters
function readEXIFData(file, start)
Now why this? Is there something missing in the function which is "still to come"?
Hello,
would you be able to explicitly state a license for this software?
Cheers
Hi all,
After solving the bug of getData
(returns always false due to a wrong boolean expression) as described in another issue, I got xml2json is undefined
. Indeed xml2json
is used in the xml2Object
(line 910 and 918) and is not defined anywhere else.
I suspect that the developers depend on something installed on their computers but not provided in the release. Anyway, given the name of the function, I assume that it converts XML data to JSON data (yes, I know, this is a quite clever deduction 😉), so I implemented a new one:
function xml2json(xml) {
var json = {};
if (xml.nodeType == 1) { // element node
if (xml.attributes.length > 0) {
json['@attributes'] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
json['@attributes'][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) { // text node
return xml.nodeValue;
}
// deal with children
if (xml.hasChildNodes()) {
for(var i = 0; i < xml.childNodes.length; i++) {
var child = xml.childNodes.item(i);
var nodeName = child.nodeName;
if (json[nodeName] == null) {
json[nodeName] = xml2json(child);
} else {
if (json[nodeName].push == null) {
var old = json[nodeName];
json[nodeName] = [];
json[nodeName].push(old);
}
json[nodeName].push(xml2json(child));
}
}
}
return json;
}
Of course, you are free to use it at your convenience.
Hi,
My camera makes extensive use of the lens fields (0xa432, 0xa433, 0xa434, 0xa435), as described here : http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
In my code, I simply added the following entries to the ExifTags
object:
// lens tags
0xA432 : "LensSpecification", // 4 rational values giving focal and aperture ranges
0xA433 : "LensMake",
0xA434 : "LensModel",
0xA435 : "LensSerialNumber",
Is is somehow possible to read exif data synchronously?
EXIF.getData(origImage, function() {
Orientation = EXIF.getTag(this, "Orientation");
});
switch (Orientation)
....
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.