UNPKG

13.9 kBJavaScriptView Raw
1/*
2 * JavaScript Load Image Exif Map
3 * https://github.com/blueimp/JavaScript-Load-Image
4 *
5 * Copyright 2013, Sebastian Tschan
6 * https://blueimp.net
7 *
8 * Exif tags mapping based on
9 * https://github.com/jseidelin/exif-js
10 *
11 * Licensed under the MIT license:
12 * https://opensource.org/licenses/MIT
13 */
14
15/* global define, module, require */
16
17;(function (factory) {
18 'use strict'
19 if (typeof define === 'function' && define.amd) {
20 // Register as an anonymous AMD module:
21 define(['./load-image', './load-image-exif'], factory)
22 } else if (typeof module === 'object' && module.exports) {
23 factory(require('./load-image'), require('./load-image-exif'))
24 } else {
25 // Browser globals:
26 factory(window.loadImage)
27 }
28})(function (loadImage) {
29 'use strict'
30
31 var ExifMapProto = loadImage.ExifMap.prototype
32
33 ExifMapProto.tags = {
34 // =================
35 // TIFF tags (IFD0):
36 // =================
37 0x0100: 'ImageWidth',
38 0x0101: 'ImageHeight',
39 0x0102: 'BitsPerSample',
40 0x0103: 'Compression',
41 0x0106: 'PhotometricInterpretation',
42 0x0112: 'Orientation',
43 0x0115: 'SamplesPerPixel',
44 0x011c: 'PlanarConfiguration',
45 0x0212: 'YCbCrSubSampling',
46 0x0213: 'YCbCrPositioning',
47 0x011a: 'XResolution',
48 0x011b: 'YResolution',
49 0x0128: 'ResolutionUnit',
50 0x0111: 'StripOffsets',
51 0x0116: 'RowsPerStrip',
52 0x0117: 'StripByteCounts',
53 0x0201: 'JPEGInterchangeFormat',
54 0x0202: 'JPEGInterchangeFormatLength',
55 0x012d: 'TransferFunction',
56 0x013e: 'WhitePoint',
57 0x013f: 'PrimaryChromaticities',
58 0x0211: 'YCbCrCoefficients',
59 0x0214: 'ReferenceBlackWhite',
60 0x0132: 'DateTime',
61 0x010e: 'ImageDescription',
62 0x010f: 'Make',
63 0x0110: 'Model',
64 0x0131: 'Software',
65 0x013b: 'Artist',
66 0x8298: 'Copyright',
67 0x8769: {
68 // ExifIFDPointer
69 0x9000: 'ExifVersion', // EXIF version
70 0xa000: 'FlashpixVersion', // Flashpix format version
71 0xa001: 'ColorSpace', // Color space information tag
72 0xa002: 'PixelXDimension', // Valid width of meaningful image
73 0xa003: 'PixelYDimension', // Valid height of meaningful image
74 0xa500: 'Gamma',
75 0x9101: 'ComponentsConfiguration', // Information about channels
76 0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel
77 0x927c: 'MakerNote', // Any desired information written by the manufacturer
78 0x9286: 'UserComment', // Comments by user
79 0xa004: 'RelatedSoundFile', // Name of related sound file
80 0x9003: 'DateTimeOriginal', // Date and time when the original image was generated
81 0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally
82 0x9010: 'OffsetTime', // Time zone when the image file was last changed
83 0x9011: 'OffsetTimeOriginal', // Time zone when the image was stored digitally
84 0x9012: 'OffsetTimeDigitized', // Time zone when the image was stored digitally
85 0x9290: 'SubSecTime', // Fractions of seconds for DateTime
86 0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal
87 0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized
88 0x829a: 'ExposureTime', // Exposure time (in seconds)
89 0x829d: 'FNumber',
90 0x8822: 'ExposureProgram', // Exposure program
91 0x8824: 'SpectralSensitivity', // Spectral sensitivity
92 0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2
93 0x8828: 'OECF', // Optoelectric conversion factor
94 0x8830: 'SensitivityType',
95 0x8831: 'StandardOutputSensitivity',
96 0x8832: 'RecommendedExposureIndex',
97 0x8833: 'ISOSpeed',
98 0x8834: 'ISOSpeedLatitudeyyy',
99 0x8835: 'ISOSpeedLatitudezzz',
100 0x9201: 'ShutterSpeedValue', // Shutter speed
101 0x9202: 'ApertureValue', // Lens aperture
102 0x9203: 'BrightnessValue', // Value of brightness
103 0x9204: 'ExposureBias', // Exposure bias
104 0x9205: 'MaxApertureValue', // Smallest F number of lens
105 0x9206: 'SubjectDistance', // Distance to subject in meters
106 0x9207: 'MeteringMode', // Metering mode
107 0x9208: 'LightSource', // Kind of light source
108 0x9209: 'Flash', // Flash status
109 0x9214: 'SubjectArea', // Location and area of main subject
110 0x920a: 'FocalLength', // Focal length of the lens in mm
111 0xa20b: 'FlashEnergy', // Strobe energy in BCPS
112 0xa20c: 'SpatialFrequencyResponse',
113 0xa20e: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit
114 0xa20f: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit
115 0xa210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution
116 0xa214: 'SubjectLocation', // Location of subject in image
117 0xa215: 'ExposureIndex', // Exposure index selected on camera
118 0xa217: 'SensingMethod', // Image sensor type
119 0xa300: 'FileSource', // Image source (3 == DSC)
120 0xa301: 'SceneType', // Scene type (1 == directly photographed)
121 0xa302: 'CFAPattern', // Color filter array geometric pattern
122 0xa401: 'CustomRendered', // Special processing
123 0xa402: 'ExposureMode', // Exposure mode
124 0xa403: 'WhiteBalance', // 1 = auto white balance, 2 = manual
125 0xa404: 'DigitalZoomRatio', // Digital zoom ratio
126 0xa405: 'FocalLengthIn35mmFilm',
127 0xa406: 'SceneCaptureType', // Type of scene
128 0xa407: 'GainControl', // Degree of overall image gain adjustment
129 0xa408: 'Contrast', // Direction of contrast processing applied by camera
130 0xa409: 'Saturation', // Direction of saturation processing applied by camera
131 0xa40a: 'Sharpness', // Direction of sharpness processing applied by camera
132 0xa40b: 'DeviceSettingDescription',
133 0xa40c: 'SubjectDistanceRange', // Distance to subject
134 0xa420: 'ImageUniqueID', // Identifier assigned uniquely to each image
135 0xa430: 'CameraOwnerName',
136 0xa431: 'BodySerialNumber',
137 0xa432: 'LensSpecification',
138 0xa433: 'LensMake',
139 0xa434: 'LensModel',
140 0xa435: 'LensSerialNumber'
141 },
142 0x8825: {
143 // GPSInfoIFDPointer
144 0x0000: 'GPSVersionID',
145 0x0001: 'GPSLatitudeRef',
146 0x0002: 'GPSLatitude',
147 0x0003: 'GPSLongitudeRef',
148 0x0004: 'GPSLongitude',
149 0x0005: 'GPSAltitudeRef',
150 0x0006: 'GPSAltitude',
151 0x0007: 'GPSTimeStamp',
152 0x0008: 'GPSSatellites',
153 0x0009: 'GPSStatus',
154 0x000a: 'GPSMeasureMode',
155 0x000b: 'GPSDOP',
156 0x000c: 'GPSSpeedRef',
157 0x000d: 'GPSSpeed',
158 0x000e: 'GPSTrackRef',
159 0x000f: 'GPSTrack',
160 0x0010: 'GPSImgDirectionRef',
161 0x0011: 'GPSImgDirection',
162 0x0012: 'GPSMapDatum',
163 0x0013: 'GPSDestLatitudeRef',
164 0x0014: 'GPSDestLatitude',
165 0x0015: 'GPSDestLongitudeRef',
166 0x0016: 'GPSDestLongitude',
167 0x0017: 'GPSDestBearingRef',
168 0x0018: 'GPSDestBearing',
169 0x0019: 'GPSDestDistanceRef',
170 0x001a: 'GPSDestDistance',
171 0x001b: 'GPSProcessingMethod',
172 0x001c: 'GPSAreaInformation',
173 0x001d: 'GPSDateStamp',
174 0x001e: 'GPSDifferential',
175 0x001f: 'GPSHPositioningError'
176 },
177 0xa005: {
178 // InteroperabilityIFDPointer
179 0x0001: 'InteroperabilityIndex'
180 }
181 }
182
183 // IFD1 directory can contain any IFD0 tags:
184 ExifMapProto.tags.ifd1 = ExifMapProto.tags
185
186 ExifMapProto.stringValues = {
187 ExposureProgram: {
188 0: 'Undefined',
189 1: 'Manual',
190 2: 'Normal program',
191 3: 'Aperture priority',
192 4: 'Shutter priority',
193 5: 'Creative program',
194 6: 'Action program',
195 7: 'Portrait mode',
196 8: 'Landscape mode'
197 },
198 MeteringMode: {
199 0: 'Unknown',
200 1: 'Average',
201 2: 'CenterWeightedAverage',
202 3: 'Spot',
203 4: 'MultiSpot',
204 5: 'Pattern',
205 6: 'Partial',
206 255: 'Other'
207 },
208 LightSource: {
209 0: 'Unknown',
210 1: 'Daylight',
211 2: 'Fluorescent',
212 3: 'Tungsten (incandescent light)',
213 4: 'Flash',
214 9: 'Fine weather',
215 10: 'Cloudy weather',
216 11: 'Shade',
217 12: 'Daylight fluorescent (D 5700 - 7100K)',
218 13: 'Day white fluorescent (N 4600 - 5400K)',
219 14: 'Cool white fluorescent (W 3900 - 4500K)',
220 15: 'White fluorescent (WW 3200 - 3700K)',
221 17: 'Standard light A',
222 18: 'Standard light B',
223 19: 'Standard light C',
224 20: 'D55',
225 21: 'D65',
226 22: 'D75',
227 23: 'D50',
228 24: 'ISO studio tungsten',
229 255: 'Other'
230 },
231 Flash: {
232 0x0000: 'Flash did not fire',
233 0x0001: 'Flash fired',
234 0x0005: 'Strobe return light not detected',
235 0x0007: 'Strobe return light detected',
236 0x0009: 'Flash fired, compulsory flash mode',
237 0x000d: 'Flash fired, compulsory flash mode, return light not detected',
238 0x000f: 'Flash fired, compulsory flash mode, return light detected',
239 0x0010: 'Flash did not fire, compulsory flash mode',
240 0x0018: 'Flash did not fire, auto mode',
241 0x0019: 'Flash fired, auto mode',
242 0x001d: 'Flash fired, auto mode, return light not detected',
243 0x001f: 'Flash fired, auto mode, return light detected',
244 0x0020: 'No flash function',
245 0x0041: 'Flash fired, red-eye reduction mode',
246 0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
247 0x0047: 'Flash fired, red-eye reduction mode, return light detected',
248 0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
249 0x004d: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
250 0x004f: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
251 0x0059: 'Flash fired, auto mode, red-eye reduction mode',
252 0x005d: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
253 0x005f: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
254 },
255 SensingMethod: {
256 1: 'Undefined',
257 2: 'One-chip color area sensor',
258 3: 'Two-chip color area sensor',
259 4: 'Three-chip color area sensor',
260 5: 'Color sequential area sensor',
261 7: 'Trilinear sensor',
262 8: 'Color sequential linear sensor'
263 },
264 SceneCaptureType: {
265 0: 'Standard',
266 1: 'Landscape',
267 2: 'Portrait',
268 3: 'Night scene'
269 },
270 SceneType: {
271 1: 'Directly photographed'
272 },
273 CustomRendered: {
274 0: 'Normal process',
275 1: 'Custom process'
276 },
277 WhiteBalance: {
278 0: 'Auto white balance',
279 1: 'Manual white balance'
280 },
281 GainControl: {
282 0: 'None',
283 1: 'Low gain up',
284 2: 'High gain up',
285 3: 'Low gain down',
286 4: 'High gain down'
287 },
288 Contrast: {
289 0: 'Normal',
290 1: 'Soft',
291 2: 'Hard'
292 },
293 Saturation: {
294 0: 'Normal',
295 1: 'Low saturation',
296 2: 'High saturation'
297 },
298 Sharpness: {
299 0: 'Normal',
300 1: 'Soft',
301 2: 'Hard'
302 },
303 SubjectDistanceRange: {
304 0: 'Unknown',
305 1: 'Macro',
306 2: 'Close view',
307 3: 'Distant view'
308 },
309 FileSource: {
310 3: 'DSC'
311 },
312 ComponentsConfiguration: {
313 0: '',
314 1: 'Y',
315 2: 'Cb',
316 3: 'Cr',
317 4: 'R',
318 5: 'G',
319 6: 'B'
320 },
321 Orientation: {
322 1: 'Original',
323 2: 'Horizontal flip',
324 3: 'Rotate 180° CCW',
325 4: 'Vertical flip',
326 5: 'Vertical flip + Rotate 90° CW',
327 6: 'Rotate 90° CW',
328 7: 'Horizontal flip + Rotate 90° CW',
329 8: 'Rotate 90° CCW'
330 }
331 }
332
333 ExifMapProto.getText = function (name) {
334 var value = this.get(name)
335 switch (name) {
336 case 'LightSource':
337 case 'Flash':
338 case 'MeteringMode':
339 case 'ExposureProgram':
340 case 'SensingMethod':
341 case 'SceneCaptureType':
342 case 'SceneType':
343 case 'CustomRendered':
344 case 'WhiteBalance':
345 case 'GainControl':
346 case 'Contrast':
347 case 'Saturation':
348 case 'Sharpness':
349 case 'SubjectDistanceRange':
350 case 'FileSource':
351 case 'Orientation':
352 return this.stringValues[name][value]
353 case 'ExifVersion':
354 case 'FlashpixVersion':
355 if (!value) return
356 return String.fromCharCode(value[0], value[1], value[2], value[3])
357 case 'ComponentsConfiguration':
358 if (!value) return
359 return (
360 this.stringValues[name][value[0]] +
361 this.stringValues[name][value[1]] +
362 this.stringValues[name][value[2]] +
363 this.stringValues[name][value[3]]
364 )
365 case 'GPSVersionID':
366 if (!value) return
367 return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]
368 }
369 return String(value)
370 }
371
372 ExifMapProto.getAll = function () {
373 var map = {}
374 var prop
375 var obj
376 var name
377 for (prop in this) {
378 if (Object.prototype.hasOwnProperty.call(this, prop)) {
379 obj = this[prop]
380 if (obj && obj.getAll) {
381 map[this.ifds[prop].name] = obj.getAll()
382 } else {
383 name = this.tags[prop]
384 if (name) map[name] = this.getText(name)
385 }
386 }
387 }
388 return map
389 }
390
391 ExifMapProto.getName = function (tagCode) {
392 var name = this.tags[tagCode]
393 if (typeof name === 'object') return this.ifds[tagCode].name
394 return name
395 }
396
397 // Extend the map of tag names to tag codes:
398 ;(function () {
399 var tags = ExifMapProto.tags
400 var prop
401 var ifd
402 var subTags
403 // Map the tag names to tags:
404 for (prop in tags) {
405 if (Object.prototype.hasOwnProperty.call(tags, prop)) {
406 ifd = ExifMapProto.ifds[prop]
407 if (ifd) {
408 subTags = tags[prop]
409 for (prop in subTags) {
410 if (Object.prototype.hasOwnProperty.call(subTags, prop)) {
411 ifd.map[subTags[prop]] = Number(prop)
412 }
413 }
414 } else {
415 ExifMapProto.map[tags[prop]] = Number(prop)
416 }
417 }
418 }
419 })()
420})