1 | # JavaScript Load Image
|
2 |
|
3 | > A JavaScript library to load and transform image files.
|
4 |
|
5 | ## Contents
|
6 |
|
7 | - [Demo](#demo)
|
8 | - [Description](#description)
|
9 | - [Setup](#setup)
|
10 | - [Usage](#usage)
|
11 | - [Image loading](#image-loading)
|
12 | - [Image scaling](#image-scaling)
|
13 | - [Requirements](#requirements)
|
14 | - [API](#api)
|
15 | - [Options](#options)
|
16 | - [maxWidth](#maxwidth)
|
17 | - [maxHeight](#maxheight)
|
18 | - [minWidth](#minwidth)
|
19 | - [minHeight](#minheight)
|
20 | - [sourceWidth](#sourcewidth)
|
21 | - [sourceHeight](#sourceheight)
|
22 | - [top](#top)
|
23 | - [right](#right)
|
24 | - [bottom](#bottom)
|
25 | - [left](#left)
|
26 | - [contain](#contain)
|
27 | - [cover](#cover)
|
28 | - [aspectRatio](#aspectratio)
|
29 | - [pixelRatio](#pixelratio)
|
30 | - [downsamplingRatio](#downsamplingratio)
|
31 | - [imageSmoothingEnabled](#imagesmoothingenabled)
|
32 | - [imageSmoothingQuality](#imagesmoothingquality)
|
33 | - [crop](#crop)
|
34 | - [orientation](#orientation)
|
35 | - [meta](#meta)
|
36 | - [canvas](#canvas)
|
37 | - [crossOrigin](#crossorigin)
|
38 | - [noRevoke](#norevoke)
|
39 | - [Meta data parsing](#meta-data-parsing)
|
40 | - [Image head](#image-head)
|
41 | - [Exif parser](#exif-parser)
|
42 | - [Exif writer](#exif-writer)
|
43 | - [IPTC parser](#iptc-parser)
|
44 | - [License](#license)
|
45 | - [Credits](#credits)
|
46 |
|
47 | ## Demo
|
48 |
|
49 | [JavaScript Load Image Demo](https://blueimp.github.io/JavaScript-Load-Image/)
|
50 |
|
51 | ## Description
|
52 |
|
53 | JavaScript Load Image is a library to load images provided as File or Blob
|
54 | objects or via URL. It returns an optionally scaled and/or cropped HTML img or
|
55 | canvas element. It also provides methods to parse image meta data to extract
|
56 | IPTC and Exif tags as well as embedded thumbnail images and to restore the
|
57 | complete image header after resizing.
|
58 |
|
59 | ## Setup
|
60 |
|
61 | Include the (combined and minified) JavaScript Load Image script in your HTML
|
62 | markup:
|
63 |
|
64 | ```html
|
65 | <script src="js/load-image.all.min.js"></script>
|
66 | ```
|
67 |
|
68 | Or alternatively, choose which components you want to include:
|
69 |
|
70 | ```html
|
71 | <script src="js/load-image.js"></script>
|
72 |
|
73 | <script src="js/load-image-scale.js"></script>
|
74 | <script src="js/load-image-meta.js"></script>
|
75 | <script src="js/load-image-fetch.js"></script>
|
76 | <script src="js/load-image-orientation.js"></script>
|
77 |
|
78 | <script src="js/load-image-exif.js"></script>
|
79 | <script src="js/load-image-exif-map.js"></script>
|
80 |
|
81 | <script src="js/load-image-iptc.js"></script>
|
82 | <script src="js/load-image-iptc-map.js"></script>
|
83 | ```
|
84 |
|
85 | ## Usage
|
86 |
|
87 | ### Image loading
|
88 |
|
89 | In your application code, use the `loadImage()` function like this:
|
90 |
|
91 | ```js
|
92 | document.getElementById('file-input').onchange = function (e) {
|
93 | loadImage(
|
94 | e.target.files[0],
|
95 | function (img) {
|
96 | document.body.appendChild(img)
|
97 | },
|
98 | { maxWidth: 600 } // Options
|
99 | )
|
100 | }
|
101 | ```
|
102 |
|
103 | ### Image scaling
|
104 |
|
105 | It is also possible to use the image scaling functionality with an existing
|
106 | image:
|
107 |
|
108 | ```js
|
109 | var scaledImage = loadImage.scale(
|
110 | img, // img or canvas element
|
111 | { maxWidth: 600 }
|
112 | )
|
113 | ```
|
114 |
|
115 | ## Requirements
|
116 |
|
117 | The JavaScript Load Image library has zero dependencies.
|
118 |
|
119 | However, JavaScript Load Image is a very suitable complement to the
|
120 | [Canvas to Blob](https://github.com/blueimp/JavaScript-Canvas-to-Blob) library.
|
121 |
|
122 | ## API
|
123 |
|
124 | The `loadImage()` function accepts a
|
125 | [File](https://developer.mozilla.org/en/DOM/File) or
|
126 | [Blob](https://developer.mozilla.org/en/DOM/Blob) object or a simple image URL
|
127 | (e.g. `'https://example.org/image.png'`) as first argument.
|
128 |
|
129 | If a [File](https://developer.mozilla.org/en/DOM/File) or
|
130 | [Blob](https://developer.mozilla.org/en/DOM/Blob) is passed as parameter, it
|
131 | returns a HTML `img` element if the browser supports the
|
132 | [URL](https://developer.mozilla.org/en/DOM/window.URL) API or a
|
133 | [FileReader](https://developer.mozilla.org/en/DOM/FileReader) object if
|
134 | supported, or `false`.
|
135 | It always returns a HTML
|
136 | [img](https://developer.mozilla.org/en/docs/HTML/Element/Img) element when
|
137 | passing an image URL:
|
138 |
|
139 | ```js
|
140 | document.getElementById('file-input').onchange = function (e) {
|
141 | var loadingImage = loadImage(
|
142 | e.target.files[0],
|
143 | function (img) {
|
144 | document.body.appendChild(img)
|
145 | },
|
146 | { maxWidth: 600 }
|
147 | )
|
148 | if (!loadingImage) {
|
149 | // Alternative code ...
|
150 | }
|
151 | }
|
152 | ```
|
153 |
|
154 | The `img` element or
|
155 | [FileReader](https://developer.mozilla.org/en/DOM/FileReader) object returned by
|
156 | the `loadImage()` function allows to abort the loading process by setting the
|
157 | `onload` and `onerror` event handlers to null:
|
158 |
|
159 | ```js
|
160 | document.getElementById('file-input').onchange = function (e) {
|
161 | var loadingImage = loadImage(
|
162 | e.target.files[0],
|
163 | function (img) {
|
164 | document.body.appendChild(img)
|
165 | },
|
166 | { maxWidth: 600 }
|
167 | )
|
168 | loadingImage.onload = loadingImage.onerror = null
|
169 | }
|
170 | ```
|
171 |
|
172 | The second argument must be a `callback` function, which is called when the
|
173 | image has been loaded or an error occurred while loading the image. The callback
|
174 | function is passed two arguments.
|
175 | The first is either an HTML `img` element, a
|
176 | [canvas](https://developer.mozilla.org/en/HTML/Canvas) element, or an
|
177 | [Event](https://developer.mozilla.org/en/DOM/event) object of type `error`.
|
178 | The second is on object with the original image dimensions as properties and
|
179 | potentially additional [meta data](#meta-data-parsing):
|
180 |
|
181 | ```js
|
182 | var imageUrl = 'https://example.org/image.png'
|
183 | loadImage(
|
184 | imageUrl,
|
185 | function (img, data) {
|
186 | if (img.type === 'error') {
|
187 | console.error('Error loading image ' + imageUrl)
|
188 | } else {
|
189 | document.body.appendChild(img)
|
190 | console.log('Original image width: ', data.originalWidth)
|
191 | console.log('Original image height: ', data.originalHeight)
|
192 | }
|
193 | },
|
194 | { maxWidth: 600 }
|
195 | )
|
196 | ```
|
197 |
|
198 | ## Options
|
199 |
|
200 | The optional third argument to `loadImage()` is a map of options.
|
201 |
|
202 | They can be used the following way:
|
203 |
|
204 | ```js
|
205 | loadImage(
|
206 | fileOrBlobOrUrl,
|
207 | function (img) {
|
208 | document.body.appendChild(img)
|
209 | },
|
210 | {
|
211 | maxWidth: 600,
|
212 | maxHeight: 300,
|
213 | minWidth: 100,
|
214 | minHeight: 50,
|
215 | canvas: true
|
216 | }
|
217 | )
|
218 | ```
|
219 |
|
220 | All settings are optional. By default, the image is returned as HTML `img`
|
221 | element without any image size restrictions.
|
222 |
|
223 | ### maxWidth
|
224 |
|
225 | Defines the maximum width of the img/canvas element.
|
226 |
|
227 | ### maxHeight
|
228 |
|
229 | Defines the maximum height of the img/canvas element.
|
230 |
|
231 | ### minWidth
|
232 |
|
233 | Defines the minimum width of the img/canvas element.
|
234 |
|
235 | ### minHeight
|
236 |
|
237 | Defines the minimum height of the img/canvas element.
|
238 |
|
239 | ### sourceWidth
|
240 |
|
241 | The width of the sub-rectangle of the source image to draw into the destination
|
242 | canvas.
|
243 | Defaults to the source image width and requires `canvas: true`.
|
244 |
|
245 | ### sourceHeight
|
246 |
|
247 | The height of the sub-rectangle of the source image to draw into the destination
|
248 | canvas.
|
249 | Defaults to the source image height and requires `canvas: true`.
|
250 |
|
251 | ### top
|
252 |
|
253 | The top margin of the sub-rectangle of the source image.
|
254 | Defaults to `0` and requires `canvas: true`.
|
255 |
|
256 | ### right
|
257 |
|
258 | The right margin of the sub-rectangle of the source image.
|
259 | Defaults to `0` and requires `canvas: true`.
|
260 |
|
261 | ### bottom
|
262 |
|
263 | The bottom margin of the sub-rectangle of the source image.
|
264 | Defaults to `0` and requires `canvas: true`.
|
265 |
|
266 | ### left
|
267 |
|
268 | The left margin of the sub-rectangle of the source image.
|
269 | Defaults to `0` and requires `canvas: true`.
|
270 |
|
271 | ### contain
|
272 |
|
273 | Scales the image up/down to contain it in the max dimensions if set to `true`.
|
274 | This emulates the CSS feature [background-image: contain](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#contain).
|
275 |
|
276 | ### cover
|
277 |
|
278 | Scales the image up/down to cover the max dimensions with the image dimensions
|
279 | if set to `true`.
|
280 | This emulates the CSS feature [background-image: cover](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Scaling_background_images#cover).
|
281 |
|
282 | ### aspectRatio
|
283 |
|
284 | Crops the image to the given aspect ratio (e.g. `16/9`).
|
285 | Setting the `aspectRatio` also enables the `crop` option.
|
286 |
|
287 | ### pixelRatio
|
288 |
|
289 | Defines the ratio of the canvas pixels to the physical image pixels on the
|
290 | screen.
|
291 | Should be set to `window.devicePixelRatio` unless the scaled image is not rendered
|
292 | on screen.
|
293 | Defaults to `1` and requires `canvas: true`.
|
294 |
|
295 | ### downsamplingRatio
|
296 |
|
297 | Defines the ratio in which the image is downsampled.
|
298 | By default, images are downsampled in one step. With a ratio of `0.5`, each step
|
299 | scales the image to half the size, before reaching the target dimensions.
|
300 | Requires `canvas: true`.
|
301 |
|
302 | ### imageSmoothingEnabled
|
303 |
|
304 | If set to `false`,
|
305 | [disables image smoothing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled).
|
306 | Defaults to `true` and requires `canvas: true`.
|
307 |
|
308 | ### imageSmoothingQuality
|
309 |
|
310 | Sets the
|
311 | [quality of image smoothing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingQuality).
|
312 | Possible values: `'low'`, `'medium'`, `'high'`
|
313 | Defaults to `'low'` and requires `canvas: true`.
|
314 |
|
315 | ### crop
|
316 |
|
317 | Crops the image to the maxWidth/maxHeight constraints if set to `true`.
|
318 | Enabling the `crop` option also enables the `canvas` option.
|
319 |
|
320 | ### orientation
|
321 |
|
322 | Transform the canvas according to the specified Exif orientation, which can be
|
323 | an `integer` in the range of `1` to `8` or the boolean value `true`.
|
324 | When set to `true`, it will set the orientation value based on the EXIF data of
|
325 | the image, which will be parsed automatically if the exif library is available.
|
326 |
|
327 | Setting `orientation` to an integer in the range of `2` to `8` enables the
|
328 | `canvas` option.
|
329 | Setting `orientation` to `true` enables the `canvas` and `meta` options, unless
|
330 | the browser supports automatic image orientation (see [browser support for image-orientation](https://caniuse.com/#feat=css-image-orientation)).
|
331 |
|
332 | ### meta
|
333 |
|
334 | Automatically parses the image meta data if set to `true`.
|
335 | The meta data is passed to the callback as part of the second argument.
|
336 | If the file is given as URL and the browser supports the
|
337 | [fetch API](https://developer.mozilla.org/en/docs/Web/API/Fetch_API), fetches
|
338 | the file as Blob to be able to parse the meta data.
|
339 |
|
340 | ### canvas
|
341 |
|
342 | Returns the image as [canvas](https://developer.mozilla.org/en/HTML/Canvas)
|
343 | element if set to `true`.
|
344 |
|
345 | ### crossOrigin
|
346 |
|
347 | Sets the crossOrigin property on the img element for loading
|
348 | [CORS enabled images](https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image).
|
349 |
|
350 | ### noRevoke
|
351 |
|
352 | By default, the
|
353 | [created object URL](https://developer.mozilla.org/en/DOM/window.URL.createObjectURL)
|
354 | is revoked after the image has been loaded, except when this option is set to
|
355 | `true`.
|
356 |
|
357 | ## Meta data parsing
|
358 |
|
359 | If the Load Image Meta extension is included, it is also possible to parse image
|
360 | meta data automatically with the `meta` option:
|
361 |
|
362 | ```js
|
363 | loadImage(
|
364 | fileOrBlobOrUrl,
|
365 | function (img, data) {
|
366 | console.log('Original image head: ', data.imageHead)
|
367 | console.log('Exif data: ', data.exif) // requires exif extension
|
368 | console.log('IPTC data: ', data.iptc) // requires iptc extension
|
369 | },
|
370 | { meta: true }
|
371 | )
|
372 | ```
|
373 |
|
374 | Or alternatively via `loadImage.parseMetaData`, which can be used with an
|
375 | available `File` or `Blob` object as first argument:
|
376 |
|
377 | ```js
|
378 | loadImage.parseMetaData(
|
379 | fileOrBlob,
|
380 | function (data) {
|
381 | console.log('Original image head: ', data.imageHead)
|
382 | console.log('Exif data: ', data.exif) // requires exif extension
|
383 | console.log('IPTC data: ', data.iptc) // requires iptc extension
|
384 | },
|
385 | {
|
386 | maxMetaDataSize: 262144
|
387 | }
|
388 | )
|
389 | ```
|
390 |
|
391 | The Meta data extension also adds additional options used for the
|
392 | `parseMetaData` method:
|
393 |
|
394 | - `maxMetaDataSize`: Maximum number of bytes of meta data to parse.
|
395 | - `disableImageHead`: Disable parsing the original image head.
|
396 | - `disableMetaDataParsers`: Disable parsing meta data (image head only)
|
397 |
|
398 | ### Image head
|
399 |
|
400 | Resized JPEG images can be combined with their original image head via
|
401 | `loadImage.replaceHead`, which requires the resized image as `Blob` object as
|
402 | first argument and an `ArrayBuffer` image head as second argument. The third
|
403 | argument must be a `callback` function, which is called with the new `Blob`
|
404 | object:
|
405 |
|
406 | ```js
|
407 | loadImage(
|
408 | fileOrBlobOrUrl,
|
409 | function (img, data) {
|
410 | if (data.imageHead && data.exif) {
|
411 | img.toBlob(function (blob) {
|
412 | loadImage.replaceHead(blob, data.imageHead, function (newBlob) {
|
413 | // do something with newBlob
|
414 | })
|
415 | }, 'image/jpeg')
|
416 | }
|
417 | },
|
418 | { meta: true, canvas: true, maxWidth: 800 }
|
419 | )
|
420 | ```
|
421 |
|
422 | **Note:**
|
423 | Blob objects of resized images can be created via
|
424 | [canvas.toBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob).
|
425 | For browsers which don't have native support, a
|
426 | [canvas.toBlob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob)
|
427 | is available.
|
428 |
|
429 | ### Exif parser
|
430 |
|
431 | If you include the Load Image Exif Parser extension, the argument passed to the
|
432 | callback for `parseMetaData` will contain the additional properties if Exif data
|
433 | could be found in the given image:
|
434 |
|
435 | - `exif`: The parsed Exif tags
|
436 | - `exifOffsets`: The parsed Exif tag offsets
|
437 | - `exifTiffOffset`: TIFF header offset (used for offset pointers)
|
438 | - `exifLittleEndian`: little endian order if true, big endian if false
|
439 |
|
440 | The `exif` object stores the parsed Exif tags:
|
441 |
|
442 | ```js
|
443 | var orientation = data.exif[0x0112] // Orientation
|
444 | ```
|
445 |
|
446 | The `exif` and `exifOffsets` objects also provide a `get()` method to retrieve
|
447 | the tag value/offset via the tag's mapped name:
|
448 |
|
449 | ```js
|
450 | var orientation = data.exif.get('Orientation')
|
451 | var orientationOffset = data.exifOffsets.get('Orientation')
|
452 | ```
|
453 |
|
454 | By default, the only available mapped names are `Orientation` and `Thumbnail`.
|
455 | If you also include the Load Image Exif Map library, additional tag mappings
|
456 | become available, as well as two additional methods, `exif.getText()` and
|
457 | `exif.getAll()`:
|
458 |
|
459 | ```js
|
460 | var flashText = data.exif.getText('Flash') // e.g.: 'Flash fired, auto mode',
|
461 |
|
462 | // A map of all parsed tags with their mapped names/text as keys/values:
|
463 | var allTags = data.exif.getAll()
|
464 | ```
|
465 |
|
466 | The Exif parser also adds additional options for the parseMetaData method, to
|
467 | disable certain aspects of the parser:
|
468 |
|
469 | - `disableExif`: Disables Exif parsing.
|
470 | - `disableExifThumbnail`: Disables parsing of the Exif Thumbnail.
|
471 | - `disableExifSub`: Disables parsing of the Exif Sub IFD.
|
472 | - `disableExifGps`: Disables parsing of the Exif GPS Info IFD.
|
473 | - `disableExifOffsets`: Disables storing Exif tag offsets
|
474 |
|
475 | ### Exif writer
|
476 |
|
477 | The Exif parser extension also includes a minimal writer that allows to override
|
478 | the Exif `Orientation` value in the parsed `imageHead` `ArrayBuffer`:
|
479 |
|
480 | ```js
|
481 | loadImage(
|
482 | fileOrBlobOrUrl,
|
483 | function (img, data) {
|
484 | if (data.imageHead && data.exif) {
|
485 | // Reset Exif Orientation data:
|
486 | loadImage.writeExifData(data.imageHead, data, 'Orientation', 1)
|
487 | img.toBlob(function (blob) {
|
488 | loadImage.replaceHead(blob, data.imageHead, function (newBlob) {
|
489 | // do something with newBlob
|
490 | })
|
491 | }, 'image/jpeg')
|
492 | }
|
493 | },
|
494 | { meta: true, orientation: true, canvas: true, maxWidth: 800 }
|
495 | )
|
496 | ```
|
497 |
|
498 | ### IPTC parser
|
499 |
|
500 | If you include the Load Image IPTC Parser extension, the argument passed to the
|
501 | callback for `parseMetaData` will contain the additional property `iptc` if IPTC
|
502 | data could be found in the given image.
|
503 | The `iptc` object stores the parsed IPTC tags:
|
504 |
|
505 | ```js
|
506 | var objectname = data.iptc[0x5]
|
507 | ```
|
508 |
|
509 | It also provides an `iptc.get()` method to retrieve the tag value via the tag's
|
510 | mapped name:
|
511 |
|
512 | ```js
|
513 | var objectname = data.iptc.get('ObjectName')
|
514 | ```
|
515 |
|
516 | By default, the only available mapped names are `ObjectName`.
|
517 | If you also include the Load Image IPTC Map library, additional tag mappings
|
518 | become available, as well as two additional methods, `iptc.getText()` and
|
519 | `iptc.getAll()`:
|
520 |
|
521 | ```js
|
522 | var keywords = data.iptc.getText('Keywords') // e.g.: ['Weather','Sky']
|
523 |
|
524 | // A map of all parsed tags with their mapped names/text as keys/values:
|
525 | var allTags = data.iptc.getAll()
|
526 | ```
|
527 |
|
528 | The IPTC parser also adds additional options for the parseMetaData method, to
|
529 | disable certain aspects of the parser:
|
530 |
|
531 | - `disableIptc`: Disables IPTC parsing.
|
532 |
|
533 | ## License
|
534 |
|
535 | The JavaScript Load Image script is released under the
|
536 | [MIT license](https://opensource.org/licenses/MIT).
|
537 |
|
538 | ## Credits
|
539 |
|
540 | - Image meta data handling implementation based on the help and contribution of
|
541 | Achim Stöhr.
|
542 | - Exif tags mapping based on Jacob Seidelin's
|
543 | [exif-js](https://github.com/jseidelin/exif-js) library.
|
544 | - IPTC parser implementation by [Dave Bevan](https://github.com/bevand10).
|