UNPKG

31.7 kBMarkdownView Raw
1# JavaScript Load Image
2
3> A JavaScript library to load and transform image files.
4
5## Contents
6
7- [Demo](https://blueimp.github.io/JavaScript-Load-Image/)
8- [Description](#description)
9- [Setup](#setup)
10- [Usage](#usage)
11 - [Image loading](#image-loading)
12 - [Image scaling](#image-scaling)
13- [Requirements](#requirements)
14- [Browser support](#browser-support)
15- [API](#api)
16 - [Callback](#callback)
17 - [Function signature](#function-signature)
18 - [Cancel image loading](#cancel-image-loading)
19 - [Callback arguments](#callback-arguments)
20 - [Error handling](#error-handling)
21 - [Promise](#promise)
22- [Options](#options)
23 - [maxWidth](#maxwidth)
24 - [maxHeight](#maxheight)
25 - [minWidth](#minwidth)
26 - [minHeight](#minheight)
27 - [sourceWidth](#sourcewidth)
28 - [sourceHeight](#sourceheight)
29 - [top](#top)
30 - [right](#right)
31 - [bottom](#bottom)
32 - [left](#left)
33 - [contain](#contain)
34 - [cover](#cover)
35 - [aspectRatio](#aspectratio)
36 - [pixelRatio](#pixelratio)
37 - [downsamplingRatio](#downsamplingratio)
38 - [imageSmoothingEnabled](#imagesmoothingenabled)
39 - [imageSmoothingQuality](#imagesmoothingquality)
40 - [crop](#crop)
41 - [orientation](#orientation)
42 - [meta](#meta)
43 - [canvas](#canvas)
44 - [crossOrigin](#crossorigin)
45 - [noRevoke](#norevoke)
46- [Metadata parsing](#metadata-parsing)
47 - [Image head](#image-head)
48 - [Exif parser](#exif-parser)
49 - [Exif Thumbnail](#exif-thumbnail)
50 - [Exif IFD](#exif-ifd)
51 - [GPSInfo IFD](#gpsinfo-ifd)
52 - [Interoperability IFD](#interoperability-ifd)
53 - [Exif parser options](#exif-parser-options)
54 - [Exif writer](#exif-writer)
55 - [IPTC parser](#iptc-parser)
56 - [IPTC parser options](#iptc-parser-options)
57- [License](#license)
58- [Credits](#credits)
59
60## Description
61
62JavaScript Load Image is a library to load images provided as `File` or `Blob`
63objects or via `URL`. It returns an optionally **scaled**, **cropped** or
64**rotated** HTML `img` or `canvas` element.
65
66It also provides methods to parse image metadata to extract
67[IPTC](https://iptc.org/standards/photo-metadata/) and
68[Exif](https://en.wikipedia.org/wiki/Exif) tags as well as embedded thumbnail
69images, to overwrite the Exif Orientation value and to restore the complete
70image header after resizing.
71
72## Setup
73
74Install via [NPM](https://www.npmjs.com/package/blueimp-load-image):
75
76```sh
77npm install blueimp-load-image
78```
79
80This will install the JavaScript files inside
81`./node_modules/blueimp-load-image/js/` relative to your current directory, from
82where you can copy them into a folder that is served by your web server.
83
84Next include the combined and minified JavaScript Load Image script in your HTML
85markup:
86
87```html
88<script src="js/load-image.all.min.js"></script>
89```
90
91Or alternatively, choose which components you want to include:
92
93```html
94<!-- required for all operations -->
95<script src="js/load-image.js"></script>
96
97<!-- required for scaling, cropping and as dependency for rotation -->
98<script src="js/load-image-scale.js"></script>
99
100<!-- required to parse meta data and to restore the complete image head -->
101<script src="js/load-image-meta.js"></script>
102
103<!-- required to parse meta data from images loaded via URL -->
104<script src="js/load-image-fetch.js"></script>
105
106<!-- required for rotation and cross-browser image orientation -->
107<script src="js/load-image-orientation.js"></script>
108
109<!-- required to parse Exif tags and cross-browser image orientation -->
110<script src="js/load-image-exif.js"></script>
111
112<!-- required to display text mappings for Exif tags -->
113<script src="js/load-image-exif-map.js"></script>
114
115<!-- required to parse IPTC tags -->
116<script src="js/load-image-iptc.js"></script>
117
118<!-- required to display text mappings for IPTC tags -->
119<script src="js/load-image-iptc-map.js"></script>
120```
121
122## Usage
123
124### Image loading
125
126In your application code, use the `loadImage()` function with
127[callback](#callback) style:
128
129```js
130document.getElementById('file-input').onchange = function () {
131 loadImage(
132 this.files[0],
133 function (img) {
134 document.body.appendChild(img)
135 },
136 { maxWidth: 600 } // Options
137 )
138}
139```
140
141Or use the [Promise](#promise) based API like this ([requires](#requirements) a
142polyfill for older browsers):
143
144```js
145document.getElementById('file-input').onchange = function () {
146 loadImage(this.files[0], { maxWidth: 600 }).then(function (data) {
147 document.body.appendChild(data.image)
148 })
149}
150```
151
152With
153[async/await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await)
154(requires a modern browser or a code transpiler like
155[Babel](https://babeljs.io/) or [TypeScript](https://www.typescriptlang.org/)):
156
157```js
158document.getElementById('file-input').onchange = async function () {
159 let data = await loadImage(this.files[0], { maxWidth: 600 })
160 document.body.appendChild(data.image)
161}
162```
163
164### Image scaling
165
166It is also possible to use the image scaling functionality directly with an
167existing image:
168
169```js
170var scaledImage = loadImage.scale(
171 img, // img or canvas element
172 { maxWidth: 600 }
173)
174```
175
176## Requirements
177
178The JavaScript Load Image library has zero dependencies, but benefits from the
179following two
180[polyfills](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill):
181
182- [blueimp-canvas-to-blob](https://github.com/blueimp/JavaScript-Canvas-to-Blob)
183 for browsers without native
184 [HTMLCanvasElement.toBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob)
185 support, to create `Blob` objects out of `canvas` elements.
186- [promise-polyfill](https://github.com/taylorhakes/promise-polyfill) to be able
187 to use the
188 [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
189 based `loadImage` API in Browsers without native `Promise` support.
190
191## Browser support
192
193Browsers which implement the following APIs support all options:
194
195- Loading images from File and Blob objects:
196 - [URL.createObjectURL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)
197 or
198 [FileReader.readAsDataURL](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL)
199- Parsing meta data:
200 - [FileReader.readAsArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsArrayBuffer)
201 - [Blob.slice](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice)
202 - [DataView](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView)
203 (no [BigInt](https://developer.mozilla.org/en-US/docs/Glossary/BigInt)
204 support required)
205- Parsing meta data from images loaded via URL:
206 - [fetch Response.blob](https://developer.mozilla.org/en-US/docs/Web/API/Body/blob)
207 or
208 [XMLHttpRequest.responseType blob](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType#blob)
209- Promise based API:
210 - [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
211
212This includes (but is not limited to) the following browsers:
213
214- Chrome 32+
215- Firefox 29+
216- Safari 8+
217- Mobile Chrome 42+ (Android)
218- Mobile Firefox 50+ (Android)
219- Mobile Safari 8+ (iOS)
220- Edge 74+
221- Edge Legacy 12+
222- Internet Explorer 10+ `*`
223
224`*` Internet Explorer [requires](#requirements) a polyfill for the `Promise`
225based API.
226
227Loading an image from a URL and applying transformations (scaling, cropping and
228rotating - except `orientation:true`, which requires reading meta data) is
229supported by all browsers which implement the
230[HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement)
231interface.
232
233Loading an image from a URL and scaling it in size is supported by all browsers
234which implement the
235[img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) element and
236has been tested successfully with browser engines as old as Internet Explorer 5
237(via
238[IE11's emulation mode](<https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/samples/dn255001(v=vs.85)>)).
239
240The `loadImage()` function applies options using
241[progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement)
242and falls back to a configuration that is supported by the browser, e.g. if the
243`canvas` element is not supported, an equivalent `img` element is returned.
244
245## API
246
247### Callback
248
249#### Function signature
250
251The `loadImage()` function accepts a
252[File](https://developer.mozilla.org/en-US/docs/Web/API/File) or
253[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object or an image
254URL as first argument.
255
256If a [File](https://developer.mozilla.org/en-US/docs/Web/API/File) or
257[Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) is passed as
258parameter, it returns an HTML `img` element if the browser supports the
259[URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) API, alternatively a
260[FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader) object
261if the `FileReader` API is supported, or `false`.
262
263It always returns an HTML
264[img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img) element
265when passing an image URL:
266
267```js
268var loadingImage = loadImage(
269 'https://example.org/image.png',
270 function (img) {
271 document.body.appendChild(img)
272 },
273 { maxWidth: 600 }
274)
275```
276
277#### Cancel image loading
278
279Some browsers (e.g. Chrome) will cancel the image loading process if the `src`
280property of an `img` element is changed.
281To avoid unnecessary requests, we can use the
282[data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs)
283of a 1x1 pixel transparent GIF image as `src` target to cancel the original
284image download.
285
286To disable callback handling, we can also unset the image event handlers and for
287maximum browser compatibility, cancel the file reading process if the returned
288object is a
289[FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)
290instance:
291
292```js
293var loadingImage = loadImage(
294 'https://example.org/image.png',
295 function (img) {
296 document.body.appendChild(img)
297 },
298 { maxWidth: 600 }
299)
300
301if (loadingImage) {
302 // Unset event handling for the loading image:
303 loadingImage.onload = loadingImage.onerror = null
304
305 // Cancel image loading process:
306 if (loadingImage.abort) {
307 // FileReader instance, stop the file reading process:
308 loadingImage.abort()
309 } else {
310 // HTMLImageElement element, cancel the original image request by changing
311 // the target source to the data URL of a 1x1 pixel transparent image GIF:
312 loadingImage.src =
313 'data:image/gif;base64,' +
314 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
315 }
316}
317```
318
319**Please note:**
320The `img` element (or `FileReader` instance) for the loading image is only
321returned when using the callback style API and not available with the
322[Promise](#promise) based API.
323
324#### Callback arguments
325
326For the callback style API, the second argument to `loadImage()` must be a
327`callback` function, which is called when the image has been loaded or an error
328occurred while loading the image.
329
330The callback function is passed two arguments:
331
3321. An HTML [img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
333 element or
334 [canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)
335 element, or an
336 [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) object of
337 type `error`.
3382. An object with the original image dimensions as properties and potentially
339 additional [metadata](#metadata-parsing).
340
341```js
342loadImage(
343 fileOrBlobOrUrl,
344 function (img, data) {
345 document.body.appendChild(img)
346 console.log('Original image width: ', data.originalWidth)
347 console.log('Original image height: ', data.originalHeight)
348 },
349 { maxWidth: 600, meta: true }
350)
351```
352
353**Please note:**
354The original image dimensions reflect the natural width and height of the loaded
355image before applying any transformation.
356For consistent values across browsers, [metadata](#metadata-parsing) parsing has
357to be enabled via `meta:true`, so `loadImage` can detect automatic image
358orientation and normalize the dimensions.
359
360#### Error handling
361
362Example code implementing error handling:
363
364```js
365loadImage(
366 fileOrBlobOrUrl,
367 function (img, data) {
368 if (img.type === 'error') {
369 console.error('Error loading image file')
370 } else {
371 document.body.appendChild(img)
372 }
373 },
374 { maxWidth: 600 }
375)
376```
377
378### Promise
379
380If the `loadImage()` function is called without a `callback` function as second
381argument and the
382[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
383API is available, it returns a `Promise` object:
384
385```js
386loadImage(fileOrBlobOrUrl, { maxWidth: 600, meta: true })
387 .then(function (data) {
388 document.body.appendChild(data.image)
389 console.log('Original image width: ', data.originalWidth)
390 console.log('Original image height: ', data.originalHeight)
391 })
392 .catch(function (err) {
393 // Handling image loading errors
394 console.log(err)
395 })
396```
397
398The `Promise` resolves with an object with the following properties:
399
400- `image`: An HTML
401 [img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) or
402 [canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) element.
403- `originalWidth`: The original width of the image.
404- `originalHeight`: The original height of the image.
405
406Please also read the note about original image dimensions normalization in the
407[callback arguments](#callback-arguments) section.
408
409If [metadata](#metadata-parsing) has been parsed, additional properties might be
410present on the object.
411
412If image loading fails, the `Promise` rejects with an
413[Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) object of type
414`error`.
415
416## Options
417
418The optional options argument to `loadImage()` allows to configure the image
419loading.
420
421It can be used the following way with the callback style:
422
423```js
424loadImage(
425 fileOrBlobOrUrl,
426 function (img) {
427 document.body.appendChild(img)
428 },
429 {
430 maxWidth: 600,
431 maxHeight: 300,
432 minWidth: 100,
433 minHeight: 50,
434 canvas: true
435 }
436)
437```
438
439Or the following way with the `Promise` based API:
440
441```js
442loadImage(fileOrBlobOrUrl, {
443 maxWidth: 600,
444 maxHeight: 300,
445 minWidth: 100,
446 minHeight: 50,
447 canvas: true
448}).then(function (data) {
449 document.body.appendChild(data.image)
450})
451```
452
453All settings are optional. By default, the image is returned as HTML `img`
454element without any image size restrictions.
455
456### maxWidth
457
458Defines the maximum width of the `img`/`canvas` element.
459
460### maxHeight
461
462Defines the maximum height of the `img`/`canvas` element.
463
464### minWidth
465
466Defines the minimum width of the `img`/`canvas` element.
467
468### minHeight
469
470Defines the minimum height of the `img`/`canvas` element.
471
472### sourceWidth
473
474The width of the sub-rectangle of the source image to draw into the destination
475canvas.
476Defaults to the source image width and requires `canvas: true`.
477
478### sourceHeight
479
480The height of the sub-rectangle of the source image to draw into the destination
481canvas.
482Defaults to the source image height and requires `canvas: true`.
483
484### top
485
486The top margin of the sub-rectangle of the source image.
487Defaults to `0` and requires `canvas: true`.
488
489### right
490
491The right margin of the sub-rectangle of the source image.
492Defaults to `0` and requires `canvas: true`.
493
494### bottom
495
496The bottom margin of the sub-rectangle of the source image.
497Defaults to `0` and requires `canvas: true`.
498
499### left
500
501The left margin of the sub-rectangle of the source image.
502Defaults to `0` and requires `canvas: true`.
503
504### contain
505
506Scales the image up/down to contain it in the max dimensions if set to `true`.
507This emulates the CSS feature
508[background-image: contain](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images#contain).
509
510### cover
511
512Scales the image up/down to cover the max dimensions with the image dimensions
513if set to `true`.
514This emulates the CSS feature
515[background-image: cover](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images#cover).
516
517### aspectRatio
518
519Crops the image to the given aspect ratio (e.g. `16/9`).
520Setting the `aspectRatio` also enables the `crop` option.
521
522### pixelRatio
523
524Defines the ratio of the canvas pixels to the physical image pixels on the
525screen.
526Should be set to
527[window.devicePixelRatio](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio)
528unless the scaled image is not rendered on screen.
529Defaults to `1` and requires `canvas: true`.
530
531### downsamplingRatio
532
533Defines the ratio in which the image is downsampled (scaled down in steps).
534By default, images are downsampled in one step.
535With a ratio of `0.5`, each step scales the image to half the size, before
536reaching the target dimensions.
537Requires `canvas: true`.
538
539### imageSmoothingEnabled
540
541If set to `false`,
542[disables image smoothing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled).
543Defaults to `true` and requires `canvas: true`.
544
545### imageSmoothingQuality
546
547Sets the
548[quality of image smoothing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingQuality).
549Possible values: `'low'`, `'medium'`, `'high'`
550Defaults to `'low'` and requires `canvas: true`.
551
552### crop
553
554Crops the image to the `maxWidth`/`maxHeight` constraints if set to `true`.
555Enabling the `crop` option also enables the `canvas` option.
556
557### orientation
558
559Transform the canvas according to the specified Exif orientation, which can be
560an `integer` in the range of `1` to `8` or the boolean value `true`.
561
562When set to `true`, it will set the orientation value based on the Exif data of
563the image, which will be parsed automatically if the Exif extension is
564available.
565
566Exif orientation values to correctly display the letter F:
567
568```
569 1 2
570 ██████ ██████
571 ██ ██
572 ████ ████
573 ██ ██
574 ██ ██
575
576 3 4
577 ██ ██
578 ██ ██
579 ████ ████
580 ██ ██
581 ██████ ██████
582
583 5 6
584██████████ ██
585██ ██ ██ ██
586██ ██████████
587
588 7 8
589 ██ ██████████
590 ██ ██ ██ ██
591██████████ ██
592```
593
594Setting `orientation` to `true` enables the `canvas` and `meta` options, unless
595the browser supports automatic image orientation (see
596[browser support for image-orientation](https://caniuse.com/#feat=css-image-orientation)).
597
598Setting `orientation` to `1` enables the `canvas` and `meta` options if the
599browser does support automatic image orientation (to allow reset of the
600orientation).
601
602Setting `orientation` to an integer in the range of `2` to `8` always enables
603the `canvas` option and also enables the `meta` option if the browser supports
604automatic image orientation (again to allow reset).
605
606### meta
607
608Automatically parses the image metadata if set to `true`.
609
610If metadata has been found, the data object passed as second argument to the
611callback function has additional properties (see
612[metadata parsing](#metadata-parsing)).
613
614If the file is given as URL and the browser supports the
615[fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) or the
616XHR
617[responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType)
618`blob`, fetches the file as `Blob` to be able to parse the metadata.
619
620### canvas
621
622Returns the image as
623[canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) element if
624set to `true`.
625
626### crossOrigin
627
628Sets the `crossOrigin` property on the `img` element for loading
629[CORS enabled images](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image).
630
631### noRevoke
632
633By default, the
634[created object URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)
635is revoked after the image has been loaded, except when this option is set to
636`true`.
637
638## Metadata parsing
639
640If the Load Image Meta extension is included, it is possible to parse image meta
641data automatically with the `meta` option:
642
643```js
644loadImage(
645 fileOrBlobOrUrl,
646 function (img, data) {
647 console.log('Original image head: ', data.imageHead)
648 console.log('Exif data: ', data.exif) // requires exif extension
649 console.log('IPTC data: ', data.iptc) // requires iptc extension
650 },
651 { meta: true }
652)
653```
654
655Or alternatively via `loadImage.parseMetaData`, which can be used with an
656available `File` or `Blob` object as first argument:
657
658```js
659loadImage.parseMetaData(
660 fileOrBlob,
661 function (data) {
662 console.log('Original image head: ', data.imageHead)
663 console.log('Exif data: ', data.exif) // requires exif extension
664 console.log('IPTC data: ', data.iptc) // requires iptc extension
665 },
666 {
667 maxMetaDataSize: 262144
668 }
669)
670```
671
672Or using the
673[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
674based API:
675
676```js
677loadImage
678 .parseMetaData(fileOrBlob, {
679 maxMetaDataSize: 262144
680 })
681 .then(function (data) {
682 console.log('Original image head: ', data.imageHead)
683 console.log('Exif data: ', data.exif) // requires exif extension
684 console.log('IPTC data: ', data.iptc) // requires iptc extension
685 })
686```
687
688The Metadata extension adds additional options used for the `parseMetaData`
689method:
690
691- `maxMetaDataSize`: Maximum number of bytes of metadata to parse.
692- `disableImageHead`: Disable parsing the original image head.
693- `disableMetaDataParsers`: Disable parsing metadata (image head only)
694
695### Image head
696
697Resized JPEG images can be combined with their original image head via
698`loadImage.replaceHead`, which requires the resized image as `Blob` object as
699first argument and an `ArrayBuffer` image head as second argument.
700
701With callback style, the third argument must be a `callback` function, which is
702called with the new `Blob` object:
703
704```js
705loadImage(
706 fileOrBlobOrUrl,
707 function (img, data) {
708 if (data.imageHead) {
709 img.toBlob(function (blob) {
710 loadImage.replaceHead(blob, data.imageHead, function (newBlob) {
711 // do something with the new Blob object
712 })
713 }, 'image/jpeg')
714 }
715 },
716 { meta: true, canvas: true, maxWidth: 800 }
717)
718```
719
720Or using the
721[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
722based API like this:
723
724```js
725loadImage(fileOrBlobOrUrl, { meta: true, canvas: true, maxWidth: 800 })
726 .then(function (data) {
727 if (!data.imageHead) throw new Error('Could not parse image metadata')
728 return new Promise(function (resolve) {
729 data.image.toBlob(function (blob) {
730 data.blob = blob
731 resolve(data)
732 }, 'image/jpeg')
733 })
734 })
735 .then(function (data) {
736 return loadImage.replaceHead(data.blob, data.imageHead)
737 })
738 .then(function (blob) {
739 // do something with the new Blob object
740 })
741 .catch(function (err) {
742 console.error(err)
743 })
744```
745
746**Please note:**
747`Blob` objects of resized images can be created via
748[HTMLCanvasElement.toBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob).
749[blueimp-canvas-to-blob](https://github.com/blueimp/JavaScript-Canvas-to-Blob)
750provides a polyfill for browsers without native `canvas.toBlob()` support.
751
752### Exif parser
753
754If you include the Load Image Exif Parser extension, the argument passed to the
755callback for `parseMetaData` will contain the following additional properties if
756Exif data could be found in the given image:
757
758- `exif`: The parsed Exif tags
759- `exifOffsets`: The parsed Exif tag offsets
760- `exifTiffOffset`: TIFF header offset (used for offset pointers)
761- `exifLittleEndian`: little endian order if true, big endian if false
762
763The `exif` object stores the parsed Exif tags:
764
765```js
766var orientation = data.exif[0x0112] // Orientation
767```
768
769The `exif` and `exifOffsets` objects also provide a `get()` method to retrieve
770the tag value/offset via the tag's mapped name:
771
772```js
773var orientation = data.exif.get('Orientation')
774var orientationOffset = data.exifOffsets.get('Orientation')
775```
776
777By default, only the following names are mapped:
778
779- `Orientation`
780- `Thumbnail` (see [Exif Thumbnail](#exif-thumbnail))
781- `Exif` (see [Exif IFD](#exif-ifd))
782- `GPSInfo` (see [GPSInfo IFD](#gpsinfo-ifd))
783- `Interoperability` (see [Interoperability IFD](#interoperability-ifd))
784
785If you also include the Load Image Exif Map library, additional tag mappings
786become available, as well as three additional methods:
787
788- `exif.getText()`
789- `exif.getName()`
790- `exif.getAll()`
791
792```js
793var orientationText = data.exif.getText('Orientation') // e.g. "Rotate 90° CW"
794
795var name = data.exif.getName(0x0112) // "Orientation"
796
797// A map of all parsed tags with their mapped names/text as keys/values:
798var allTags = data.exif.getAll()
799```
800
801#### Exif Thumbnail
802
803Example code displaying a thumbnail image embedded into the Exif metadata:
804
805```js
806loadImage(
807 fileOrBlobOrUrl,
808 function (img, data) {
809 var exif = data.exif
810 var thumbnail = exif && exif.get('Thumbnail')
811 var blob = thumbnail && thumbnail.get('Blob')
812 if (blob) {
813 loadImage(
814 blob,
815 function (thumbImage) {
816 document.body.appendChild(thumbImage)
817 },
818 { orientation: exif.get('Orientation') }
819 )
820 }
821 },
822 { meta: true }
823)
824```
825
826#### Exif IFD
827
828Example code displaying data from the Exif IFD (Image File Directory) that
829contains Exif specified TIFF tags:
830
831```js
832loadImage(
833 fileOrBlobOrUrl,
834 function (img, data) {
835 var exifIFD = data.exif && data.exif.get('Exif')
836 if (exifIFD) {
837 // Map of all Exif IFD tags with their mapped names/text as keys/values:
838 console.log(exifIFD.getAll())
839 // A specific Exif IFD tag value:
840 console.log(exifIFD.get('UserComment'))
841 }
842 },
843 { meta: true }
844)
845```
846
847#### GPSInfo IFD
848
849Example code displaying data from the Exif IFD (Image File Directory) that
850contains [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System) info:
851
852```js
853loadImage(
854 fileOrBlobOrUrl,
855 function (img, data) {
856 var gpsInfo = data.exif && data.exif.get('GPSInfo')
857 if (gpsInfo) {
858 // Map of all GPSInfo tags with their mapped names/text as keys/values:
859 console.log(gpsInfo.getAll())
860 // A specific GPSInfo tag value:
861 console.log(gpsInfo.get('GPSLatitude'))
862 }
863 },
864 { meta: true }
865)
866```
867
868#### Interoperability IFD
869
870Example code displaying data from the Exif IFD (Image File Directory) that
871contains Interoperability data:
872
873```js
874loadImage(
875 fileOrBlobOrUrl,
876 function (img, data) {
877 var interoperabilityData = data.exif && data.exif.get('Interoperability')
878 if (interoperabilityData) {
879 // The InteroperabilityIndex tag value:
880 console.log(interoperabilityData.get('InteroperabilityIndex'))
881 }
882 },
883 { meta: true }
884)
885```
886
887#### Exif parser options
888
889The Exif parser adds additional options:
890
891- `disableExif`: Disables Exif parsing when `true`.
892- `disableExifOffsets`: Disables storing Exif tag offsets when `true`.
893- `includeExifTags`: A map of Exif tags to include for parsing (includes all but
894 the excluded tags by default).
895- `excludeExifTags`: A map of Exif tags to exclude from parsing (defaults to
896 exclude `Exif` `MakerNote`).
897
898An example parsing only Orientation, Thumbnail and ExifVersion tags:
899
900```js
901loadImage.parseMetaData(
902 fileOrBlob,
903 function (data) {
904 console.log('Exif data: ', data.exif)
905 },
906 {
907 includeExifTags: {
908 0x0112: true, // Orientation
909 ifd1: {
910 0x0201: true, // JPEGInterchangeFormat (Thumbnail data offset)
911 0x0202: true // JPEGInterchangeFormatLength (Thumbnail data length)
912 },
913 0x8769: {
914 // ExifIFDPointer
915 0x9000: true // ExifVersion
916 }
917 }
918 }
919)
920```
921
922An example excluding `Exif` `MakerNote` and `GPSInfo`:
923
924```js
925loadImage.parseMetaData(
926 fileOrBlob,
927 function (data) {
928 console.log('Exif data: ', data.exif)
929 },
930 {
931 excludeExifTags: {
932 0x8769: {
933 // ExifIFDPointer
934 0x927c: true // MakerNote
935 },
936 0x8825: true // GPSInfoIFDPointer
937 }
938 }
939)
940```
941
942### Exif writer
943
944The Exif parser extension also includes a minimal writer that allows to override
945the Exif `Orientation` value in the parsed `imageHead` `ArrayBuffer`:
946
947```js
948loadImage(
949 fileOrBlobOrUrl,
950 function (img, data) {
951 if (data.imageHead && data.exif) {
952 // Reset Exif Orientation data:
953 loadImage.writeExifData(data.imageHead, data, 'Orientation', 1)
954 img.toBlob(function (blob) {
955 loadImage.replaceHead(blob, data.imageHead, function (newBlob) {
956 // do something with newBlob
957 })
958 }, 'image/jpeg')
959 }
960 },
961 { meta: true, orientation: true, canvas: true, maxWidth: 800 }
962)
963```
964
965**Please note:**
966The Exif writer relies on the Exif tag offsets being available as
967`data.exifOffsets` property, which requires that Exif data has been parsed from
968the image.
969The Exif writer can only change existing values, not add new tags, e.g. it
970cannot add an Exif `Orientation` tag for an image that does not have one.
971
972### IPTC parser
973
974If you include the Load Image IPTC Parser extension, the argument passed to the
975callback for `parseMetaData` will contain the following additional properties if
976IPTC data could be found in the given image:
977
978- `iptc`: The parsed IPTC tags
979- `iptcOffsets`: The parsed IPTC tag offsets
980
981The `iptc` object stores the parsed IPTC tags:
982
983```js
984var objectname = data.iptc[5]
985```
986
987The `iptc` and `iptcOffsets` objects also provide a `get()` method to retrieve
988the tag value/offset via the tag's mapped name:
989
990```js
991var objectname = data.iptc.get('ObjectName')
992```
993
994By default, only the following names are mapped:
995
996- `ObjectName`
997
998If you also include the Load Image IPTC Map library, additional tag mappings
999become available, as well as three additional methods:
1000
1001- `iptc.getText()`
1002- `iptc.getName()`
1003- `iptc.getAll()`
1004
1005```js
1006var keywords = data.iptc.getText('Keywords') // e.g.: ['Weather','Sky']
1007
1008var name = data.iptc.getName(5) // ObjectName
1009
1010// A map of all parsed tags with their mapped names/text as keys/values:
1011var allTags = data.iptc.getAll()
1012```
1013
1014#### IPTC parser options
1015
1016The IPTC parser adds additional options:
1017
1018- `disableIptc`: Disables IPTC parsing when true.
1019- `disableIptcOffsets`: Disables storing IPTC tag offsets when `true`.
1020- `includeIptcTags`: A map of IPTC tags to include for parsing (includes all but
1021 the excluded tags by default).
1022- `excludeIptcTags`: A map of IPTC tags to exclude from parsing (defaults to
1023 exclude `ObjectPreviewData`).
1024
1025An example parsing only the `ObjectName` tag:
1026
1027```js
1028loadImage.parseMetaData(
1029 fileOrBlob,
1030 function (data) {
1031 console.log('IPTC data: ', data.iptc)
1032 },
1033 {
1034 includeIptcTags: {
1035 5: true // ObjectName
1036 }
1037 }
1038)
1039```
1040
1041An example excluding `ApplicationRecordVersion` and `ObjectPreviewData`:
1042
1043```js
1044loadImage.parseMetaData(
1045 fileOrBlob,
1046 function (data) {
1047 console.log('IPTC data: ', data.iptc)
1048 },
1049 {
1050 excludeIptcTags: {
1051 0: true, // ApplicationRecordVersion
1052 202: true // ObjectPreviewData
1053 }
1054 }
1055)
1056```
1057
1058## License
1059
1060The JavaScript Load Image library is released under the
1061[MIT license](https://opensource.org/licenses/MIT).
1062
1063## Credits
1064
1065- Original image metadata handling implemented with the help and contribution of
1066 Achim Stöhr.
1067- Original Exif tags mapping based on Jacob Seidelin's
1068 [exif-js](https://github.com/exif-js/exif-js) library.
1069- Original IPTC parser implementation by
1070 [Dave Bevan](https://github.com/bevand10).