├── .gitignore ├── .npmignore ├── History.md ├── test ├── fixtures │ └── forest.jpeg └── index.js ├── Makefile ├── bench └── index.js ├── package.json ├── index.js └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | support 2 | test 3 | examples 4 | *.sock 5 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.0.1 / 2010-01-03 3 | ================== 4 | 5 | * Initial release 6 | -------------------------------------------------------------------------------- /test/fixtures/forest.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tj/node-exif/HEAD/test/fixtures/forest.jpeg -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | test: 3 | @./node_modules/.bin/mocha \ 4 | --require should \ 5 | --reporter spec 6 | 7 | bench: 8 | @./node_modules/.bin/matcha \ 9 | bench/index.js 10 | 11 | .PHONY: test bench -------------------------------------------------------------------------------- /bench/index.js: -------------------------------------------------------------------------------- 1 | 2 | var exif = require('..'); 3 | var fs = require('fs'); 4 | var buf = fs.readFileSync('test/fixtures/forest.jpeg'); 5 | 6 | suite('exif()', function(){ 7 | bench('file', function(next){ 8 | exif('test/fixtures/image.jpg', next); 9 | }) 10 | }) -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 2 | var exif = require('..'); 3 | var assert = require('better-assert'); 4 | 5 | describe('exif(file, fn)', function(){ 6 | it('respond with EXIF json data', function(done){ 7 | exif('test/fixtures/forest.jpeg', function(err, o){ 8 | if (err) return done(err); 9 | assert('forest.jpeg' == o['file name']); 10 | done(); 11 | }); 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exif2", 3 | "version": "0.0.1", 4 | "description": "EXIF extraction with exiftool", 5 | "keywords": [], 6 | "author": "TJ Holowaychuk ", 7 | "dependencies": { 8 | "shelly": "0.0.3" 9 | }, 10 | "devDependencies": { 11 | "mocha": "*", 12 | "better-assert": "*", 13 | "matcha": "~0.3.0" 14 | }, 15 | "main": "index" 16 | } 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var exec = require('child_process').exec 7 | , command = require('shelly'); 8 | 9 | /** 10 | * Fetch EXIF data from `file` and invoke `fn(err, data)`. 11 | * 12 | * @param {String} file 13 | * @param {Function} fn 14 | * @api public 15 | */ 16 | 17 | module.exports = function(file, fn){ 18 | var cmd = command('exiftool ?', file); 19 | exec(cmd, function(err, str){ 20 | if (err) return fn(err); 21 | 22 | var obj = str.split('\n').reduce(function(obj, line){ 23 | var i = line.indexOf(':'); 24 | var key = slug(line.slice(0, i)); 25 | var val = line.slice(i + 1, line.length).trim(); 26 | if ('' == key || '' == val) return obj; 27 | obj[key] = val; 28 | return obj; 29 | }, {}); 30 | 31 | fn(null, obj); 32 | }); 33 | }; 34 | 35 | /** 36 | * Slug `str`. 37 | */ 38 | 39 | function slug(str) { 40 | return str 41 | .trim() 42 | .replace(/[^\w]+/g, ' ') 43 | .toLowerCase(); 44 | } 45 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # exif 3 | 4 | EXIF extraction with exiftool. 5 | 6 | __NOTE__: use https://github.com/LearnBoost/node-libexif if compiling is not a problem, 7 | it uses native bindings and is __much__ faster. 8 | 9 | ## Installation 10 | 11 | $ npm install exif2 12 | 13 | ### Example 14 | 15 | ```js 16 | var exif = require('exif'); 17 | 18 | exif(file, function(err, obj){ 19 | console.log(obj); 20 | }) 21 | ``` 22 | 23 | ```json 24 | { 25 | "exiftool version number": "9.08", 26 | "file name": "forest.jpeg", 27 | "directory": "test/fixtures", 28 | "file size": "497 kB", 29 | "file modification date time": "2012:12:11 14:45:59-08:00", 30 | "file access date time": "2012:12:13 16:18:36-08:00", 31 | "file inode change date time": "2012:12:11 14:45:59-08:00", 32 | "file permissions": "rw-------", 33 | "file type": "JPEG", 34 | "mime type": "image/jpeg", 35 | "jfif version": "1.01", 36 | "exif byte order": "Big-endian (Motorola, MM)", 37 | "photometric interpretation": "Color Filter Array", 38 | "make": "NIKON CORPORATION", 39 | "camera model name": "NIKON D7000", 40 | "orientation": "Horizontal (normal)", 41 | "x resolution": "72", 42 | "y resolution": "72", 43 | "resolution unit": "inches", 44 | "software": "Pixelmator 2.1.1", 45 | "modify date": "2012:10:08 19:10:63.50", 46 | "exposure time": "1/80", 47 | "f number": "5.6", 48 | "exposure program": "Aperture-priority AE", 49 | "iso": "500", 50 | "date time original": "2012:10:07 11:36:30.50", 51 | "create date": "2012:10:07 11:36:30.50", 52 | "exposure compensation": "-2", 53 | "max aperture value": "4.0", 54 | "metering mode": "Multi-segment", 55 | "light source": "Unknown", 56 | "flash": "Off, Did not fire", 57 | "focal length": "10.0 mm (35 mm equivalent: 15.0 mm)", 58 | "sub sec time": "50", 59 | "sub sec time original": "50", 60 | "sub sec time digitized": "50", 61 | "color space": "sRGB", 62 | "exif image width": "1971", 63 | "exif image height": "1306", 64 | "sensing method": "One-chip color area", 65 | "custom rendered": "Normal", 66 | "exposure mode": "Auto", 67 | "white balance": "Auto", 68 | "digital zoom ratio": "1", 69 | "focal length in 35mm format": "15 mm", 70 | "scene capture type": "Standard", 71 | "gain control": "Low gain up", 72 | "contrast": "Normal", 73 | "saturation": "Normal", 74 | "sharpness": "Normal", 75 | "subject distance range": "Unknown", 76 | "profile cmm type": "Lino", 77 | "profile version": "2.1.0", 78 | "profile class": "Display Device Profile", 79 | "color space data": "RGB", 80 | "profile connection space": "XYZ", 81 | "profile date time": "1998:02:09 06:49:00", 82 | "profile file signature": "acsp", 83 | "primary platform": "Microsoft Corporation", 84 | "cmm flags": "Not Embedded, Independent", 85 | "device manufacturer": "IEC", 86 | "device model": "sRGB", 87 | "device attributes": "Reflective, Glossy, Positive, Color", 88 | "rendering intent": "Perceptual", 89 | "connection space illuminant": "0.9642 1 0.82491", 90 | "profile creator": "HP", 91 | "profile id": "0", 92 | "profile copyright": "Copyright (c) 1998 Hewlett-Packard Company", 93 | "profile description": "sRGB IEC61966-2.1", 94 | "media white point": "0.95045 1 1.08905", 95 | "media black point": "0 0 0", 96 | "red matrix column": "0.43607 0.22249 0.01392", 97 | "green matrix column": "0.38515 0.71687 0.09708", 98 | "blue matrix column": "0.14307 0.06061 0.7141", 99 | "device mfg desc": "IEC http://www.iec.ch", 100 | "device model desc": "IEC 61966-2.1 Default RGB colour space - sRGB", 101 | "viewing cond desc": "Reference Viewing Condition in IEC61966-2.1", 102 | "viewing cond illuminant": "19.6445 20.3718 16.8089", 103 | "viewing cond surround": "3.92889 4.07439 3.36179", 104 | "viewing cond illuminant type": "D50", 105 | "luminance": "76.03647 80 87.12462", 106 | "measurement observer": "CIE 1931", 107 | "measurement backing": "0 0 0", 108 | "measurement geometry": "Unknown (0)", 109 | "measurement flare": "0.999%", 110 | "measurement illuminant": "D65", 111 | "technology": "Cathode Ray Tube Display", 112 | "red tone reproduction curve": "(Binary data 2060 bytes, use -b option to extract)", 113 | "green tone reproduction curve": "(Binary data 2060 bytes, use -b option to extract)", 114 | "blue tone reproduction curve": "(Binary data 2060 bytes, use -b option to extract)", 115 | "xmp toolkit": "XMP Core 4.4.0", 116 | "serial number": "5044750", 117 | "lens": "Sigma 10-20mm F4-5.6 EX DC HSM", 118 | "image number": "6069", 119 | "flash compensation": "0", 120 | "image width": "900", 121 | "image height": "596", 122 | "encoding process": "Baseline DCT, Huffman coding", 123 | "bits per sample": "8", 124 | "color components": "3", 125 | "y cb cr sub sampling": "YCbCr4:4:4 (1 1)", 126 | "aperture": "5.6", 127 | "image size": "900x596", 128 | "scale factor to 35 mm equivalent": "1.5", 129 | "shutter speed": "1/80", 130 | "circle of confusion": "0.020 mm", 131 | "field of view": "100.4 deg", 132 | "hyperfocal distance": "0.89 m", 133 | "lens id": "Unknown (809257734)", 134 | "light value": "9.0" 135 | } 136 | ``` 137 | 138 | ## License 139 | 140 | MIT 141 | --------------------------------------------------------------------------------