├── .gitattributes
├── arrow.png
├── index.html
├── index.js
├── node_modules
└── blueimp-load-image
│ ├── LICENSE.txt
│ ├── README.md
│ ├── js
│ ├── index.js
│ ├── load-image-exif-map.js
│ ├── load-image-exif.js
│ ├── load-image-fetch.js
│ ├── load-image-iptc-map.js
│ ├── load-image-iptc.js
│ ├── load-image-meta.js
│ ├── load-image-orientation.js
│ ├── load-image-scale.js
│ ├── load-image.all.min.js
│ ├── load-image.all.min.js.map
│ └── load-image.js
│ └── package.json
├── package-lock.json
├── package.json
└── spinner3.gif
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/racky7/image-background-remover/f9f6c8c70609c1249b1af671144afff6b8b601fc/arrow.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Remove Background
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Remove Image Background
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | |
23 | |
24 | |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | document
2 | .querySelector("input[type=file]")
3 | .addEventListener("change", async function () {
4 | const resizedImage = await loadImage(this.files[0], {
5 |
6 | //resizing image using blue-load-image module
7 |
8 | maxWidth: 1500,
9 | maxHeight: 1500,
10 | canvas: true
11 | });
12 |
13 | resizedImage.image.toBlob(async function (inputBlob) {
14 | const formData = new FormData();
15 |
16 | //display table
17 |
18 | document.getElementById("myTable").removeAttribute("Hidden");
19 |
20 | //display input image
21 | const inputImage = document.createElement("img");
22 | document.querySelector("#result1").appendChild(inputImage);
23 | inputImage.style.width = "250px";
24 | inputImage.style.height = "250px";
25 | inputImage.src = URL.createObjectURL(inputBlob);
26 |
27 | //display loader
28 |
29 | const conImage = document.createElement("img");
30 | document.querySelector("#convert").appendChild(conImage);
31 | conImage.style.width = "25%";
32 | conImage.src = "spinner3.gif";
33 |
34 | //api call
35 | formData.append("image_file", inputBlob);
36 |
37 | const response = await fetch("https://sdk.photoroom.com/v1/segment", {
38 | method: "POST",
39 | headers: {
40 | "x-api-key": process.env.APIKEY
41 | },
42 | body: formData
43 | });
44 |
45 |
46 | //output image
47 |
48 | const outputBlob = await response.blob();
49 | conImage.src = "arrow.png";
50 | conImage.style.marginTop = "20%";
51 |
52 | const outputImage = document.createElement("img");
53 | document.querySelector("#result").appendChild(outputImage);
54 | outputImage.style.width = "250px";
55 | outputImage.style.height = "250px";
56 | outputImage.src = URL.createObjectURL(outputBlob);
57 |
58 | //download button
59 |
60 | const getImg = document.createElement("a");
61 | const downBtn = document.querySelector("#downBtn");
62 | downBtn.appendChild(getImg);
63 | downBtn.removeAttribute("Hidden");
64 | getImg.href = URL.createObjectURL(outputBlob);
65 | getImg.style.textDecoration = "none";
66 | getImg.style.color = "inherit";
67 | getImg.download = "removed-bg-image";
68 | getImg.innerText = "Download (PNG)";
69 |
70 | //display clear button
71 |
72 | const clearBtn = document.querySelector("#clearBtn");
73 | clearBtn.removeAttribute("Hidden");
74 |
75 |
76 |
77 |
78 | });
79 | })
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright © 2011 Sebastian Tschan, https://blueimp.net
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/README.md:
--------------------------------------------------------------------------------
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 |
62 | JavaScript Load Image is a library to load images provided as `File` or `Blob`
63 | objects or via `URL`. It returns an optionally **scaled**, **cropped** or
64 | **rotated** HTML `img` or `canvas` element.
65 |
66 | It 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
69 | images, to overwrite the Exif Orientation value and to restore the complete
70 | image header after resizing.
71 |
72 | ## Setup
73 |
74 | Install via [NPM](https://www.npmjs.com/package/blueimp-load-image):
75 |
76 | ```sh
77 | npm install blueimp-load-image
78 | ```
79 |
80 | This will install the JavaScript files inside
81 | `./node_modules/blueimp-load-image/js/` relative to your current directory, from
82 | where you can copy them into a folder that is served by your web server.
83 |
84 | Next include the combined and minified JavaScript Load Image script in your HTML
85 | markup:
86 |
87 | ```html
88 |
89 | ```
90 |
91 | Or alternatively, choose which components you want to include:
92 |
93 | ```html
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | ```
121 |
122 | ## Usage
123 |
124 | ### Image loading
125 |
126 | In your application code, use the `loadImage()` function with
127 | [callback](#callback) style:
128 |
129 | ```js
130 | document.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 |
141 | Or use the [Promise](#promise) based API like this ([requires](#requirements) a
142 | polyfill for older browsers):
143 |
144 | ```js
145 | document.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 |
152 | With
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
158 | document.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 |
166 | It is also possible to use the image scaling functionality directly with an
167 | existing image:
168 |
169 | ```js
170 | var scaledImage = loadImage.scale(
171 | img, // img or canvas element
172 | { maxWidth: 600 }
173 | )
174 | ```
175 |
176 | ## Requirements
177 |
178 | The JavaScript Load Image library has zero dependencies, but benefits from the
179 | following 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 |
193 | Browsers 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 |
212 | This 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`
225 | based API.
226 |
227 | Loading an image from a URL and applying transformations (scaling, cropping and
228 | rotating - except `orientation:true`, which requires reading meta data) is
229 | supported by all browsers which implement the
230 | [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement)
231 | interface.
232 |
233 | Loading an image from a URL and scaling it in size is supported by all browsers
234 | which implement the
235 | [img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) element and
236 | has been tested successfully with browser engines as old as Internet Explorer 5
237 | (via
238 | [IE11's emulation mode]()).
239 |
240 | The `loadImage()` function applies options using
241 | [progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement)
242 | and 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 |
251 | The `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
254 | URL as first argument.
255 |
256 | If 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
258 | parameter, 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
261 | if the `FileReader` API is supported, or `false`.
262 |
263 | It always returns an HTML
264 | [img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img) element
265 | when passing an image URL:
266 |
267 | ```js
268 | var 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 |
279 | Some browsers (e.g. Chrome) will cancel the image loading process if the `src`
280 | property of an `img` element is changed.
281 | To avoid unnecessary requests, we can use the
282 | [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs)
283 | of a 1x1 pixel transparent GIF image as `src` target to cancel the original
284 | image download.
285 |
286 | To disable callback handling, we can also unset the image event handlers and for
287 | maximum browser compatibility, cancel the file reading process if the returned
288 | object is a
289 | [FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)
290 | instance:
291 |
292 | ```js
293 | var loadingImage = loadImage(
294 | 'https://example.org/image.png',
295 | function (img) {
296 | document.body.appendChild(img)
297 | },
298 | { maxWidth: 600 }
299 | )
300 |
301 | if (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:**
320 | The `img` element (or `FileReader` instance) for the loading image is only
321 | returned when using the callback style API and not available with the
322 | [Promise](#promise) based API.
323 |
324 | #### Callback arguments
325 |
326 | For 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
328 | occurred while loading the image.
329 |
330 | The callback function is passed two arguments:
331 |
332 | 1. 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`.
338 | 2. An object with the original image dimensions as properties and potentially
339 | additional [metadata](#metadata-parsing).
340 |
341 | ```js
342 | loadImage(
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:**
354 | The original image dimensions reflect the natural width and height of the loaded
355 | image before applying any transformation.
356 | For consistent values across browsers, [metadata](#metadata-parsing) parsing has
357 | to be enabled via `meta:true`, so `loadImage` can detect automatic image
358 | orientation and normalize the dimensions.
359 |
360 | #### Error handling
361 |
362 | Example code implementing error handling:
363 |
364 | ```js
365 | loadImage(
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 |
380 | If the `loadImage()` function is called without a `callback` function as second
381 | argument and the
382 | [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
383 | API is available, it returns a `Promise` object:
384 |
385 | ```js
386 | loadImage(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 |
398 | The `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 |
406 | Please also read the note about original image dimensions normalization in the
407 | [callback arguments](#callback-arguments) section.
408 |
409 | If [metadata](#metadata-parsing) has been parsed, additional properties might be
410 | present on the object.
411 |
412 | If 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 |
418 | The optional options argument to `loadImage()` allows to configure the image
419 | loading.
420 |
421 | It can be used the following way with the callback style:
422 |
423 | ```js
424 | loadImage(
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 |
439 | Or the following way with the `Promise` based API:
440 |
441 | ```js
442 | loadImage(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 |
453 | All settings are optional. By default, the image is returned as HTML `img`
454 | element without any image size restrictions.
455 |
456 | ### maxWidth
457 |
458 | Defines the maximum width of the `img`/`canvas` element.
459 |
460 | ### maxHeight
461 |
462 | Defines the maximum height of the `img`/`canvas` element.
463 |
464 | ### minWidth
465 |
466 | Defines the minimum width of the `img`/`canvas` element.
467 |
468 | ### minHeight
469 |
470 | Defines the minimum height of the `img`/`canvas` element.
471 |
472 | ### sourceWidth
473 |
474 | The width of the sub-rectangle of the source image to draw into the destination
475 | canvas.
476 | Defaults to the source image width and requires `canvas: true`.
477 |
478 | ### sourceHeight
479 |
480 | The height of the sub-rectangle of the source image to draw into the destination
481 | canvas.
482 | Defaults to the source image height and requires `canvas: true`.
483 |
484 | ### top
485 |
486 | The top margin of the sub-rectangle of the source image.
487 | Defaults to `0` and requires `canvas: true`.
488 |
489 | ### right
490 |
491 | The right margin of the sub-rectangle of the source image.
492 | Defaults to `0` and requires `canvas: true`.
493 |
494 | ### bottom
495 |
496 | The bottom margin of the sub-rectangle of the source image.
497 | Defaults to `0` and requires `canvas: true`.
498 |
499 | ### left
500 |
501 | The left margin of the sub-rectangle of the source image.
502 | Defaults to `0` and requires `canvas: true`.
503 |
504 | ### contain
505 |
506 | Scales the image up/down to contain it in the max dimensions if set to `true`.
507 | This 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 |
512 | Scales the image up/down to cover the max dimensions with the image dimensions
513 | if set to `true`.
514 | This 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 |
519 | Crops the image to the given aspect ratio (e.g. `16/9`).
520 | Setting the `aspectRatio` also enables the `crop` option.
521 |
522 | ### pixelRatio
523 |
524 | Defines the ratio of the canvas pixels to the physical image pixels on the
525 | screen.
526 | Should be set to
527 | [window.devicePixelRatio](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio)
528 | unless the scaled image is not rendered on screen.
529 | Defaults to `1` and requires `canvas: true`.
530 |
531 | ### downsamplingRatio
532 |
533 | Defines the ratio in which the image is downsampled (scaled down in steps).
534 | By default, images are downsampled in one step.
535 | With a ratio of `0.5`, each step scales the image to half the size, before
536 | reaching the target dimensions.
537 | Requires `canvas: true`.
538 |
539 | ### imageSmoothingEnabled
540 |
541 | If set to `false`,
542 | [disables image smoothing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled).
543 | Defaults to `true` and requires `canvas: true`.
544 |
545 | ### imageSmoothingQuality
546 |
547 | Sets the
548 | [quality of image smoothing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/imageSmoothingQuality).
549 | Possible values: `'low'`, `'medium'`, `'high'`
550 | Defaults to `'low'` and requires `canvas: true`.
551 |
552 | ### crop
553 |
554 | Crops the image to the `maxWidth`/`maxHeight` constraints if set to `true`.
555 | Enabling the `crop` option also enables the `canvas` option.
556 |
557 | ### orientation
558 |
559 | Transform the canvas according to the specified Exif orientation, which can be
560 | an `integer` in the range of `1` to `8` or the boolean value `true`.
561 |
562 | When set to `true`, it will set the orientation value based on the Exif data of
563 | the image, which will be parsed automatically if the Exif extension is
564 | available.
565 |
566 | Exif 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 |
594 | Setting `orientation` to `true` enables the `canvas` and `meta` options, unless
595 | the browser supports automatic image orientation (see
596 | [browser support for image-orientation](https://caniuse.com/#feat=css-image-orientation)).
597 |
598 | Setting `orientation` to `1` enables the `canvas` and `meta` options if the
599 | browser does support automatic image orientation (to allow reset of the
600 | orientation).
601 |
602 | Setting `orientation` to an integer in the range of `2` to `8` always enables
603 | the `canvas` option and also enables the `meta` option if the browser supports
604 | automatic image orientation (again to allow reset).
605 |
606 | ### meta
607 |
608 | Automatically parses the image metadata if set to `true`.
609 |
610 | If metadata has been found, the data object passed as second argument to the
611 | callback function has additional properties (see
612 | [metadata parsing](#metadata-parsing)).
613 |
614 | If 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
616 | XHR
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 |
622 | Returns the image as
623 | [canvas](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) element if
624 | set to `true`.
625 |
626 | ### crossOrigin
627 |
628 | Sets 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 |
633 | By default, the
634 | [created object URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)
635 | is revoked after the image has been loaded, except when this option is set to
636 | `true`.
637 |
638 | ## Metadata parsing
639 |
640 | If the Load Image Meta extension is included, it is possible to parse image meta
641 | data automatically with the `meta` option:
642 |
643 | ```js
644 | loadImage(
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 |
655 | Or alternatively via `loadImage.parseMetaData`, which can be used with an
656 | available `File` or `Blob` object as first argument:
657 |
658 | ```js
659 | loadImage.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 |
672 | Or using the
673 | [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
674 | based API:
675 |
676 | ```js
677 | loadImage
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 |
688 | The Metadata extension adds additional options used for the `parseMetaData`
689 | method:
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 |
697 | Resized JPEG images can be combined with their original image head via
698 | `loadImage.replaceHead`, which requires the resized image as `Blob` object as
699 | first argument and an `ArrayBuffer` image head as second argument.
700 |
701 | With callback style, the third argument must be a `callback` function, which is
702 | called with the new `Blob` object:
703 |
704 | ```js
705 | loadImage(
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 |
720 | Or using the
721 | [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
722 | based API like this:
723 |
724 | ```js
725 | loadImage(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)
750 | provides a polyfill for browsers without native `canvas.toBlob()` support.
751 |
752 | ### Exif parser
753 |
754 | If you include the Load Image Exif Parser extension, the argument passed to the
755 | callback for `parseMetaData` will contain the following additional properties if
756 | Exif 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 |
763 | The `exif` object stores the parsed Exif tags:
764 |
765 | ```js
766 | var orientation = data.exif[0x0112] // Orientation
767 | ```
768 |
769 | The `exif` and `exifOffsets` objects also provide a `get()` method to retrieve
770 | the tag value/offset via the tag's mapped name:
771 |
772 | ```js
773 | var orientation = data.exif.get('Orientation')
774 | var orientationOffset = data.exifOffsets.get('Orientation')
775 | ```
776 |
777 | By 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 |
785 | If you also include the Load Image Exif Map library, additional tag mappings
786 | become available, as well as three additional methods:
787 |
788 | - `exif.getText()`
789 | - `exif.getName()`
790 | - `exif.getAll()`
791 |
792 | ```js
793 | var orientationText = data.exif.getText('Orientation') // e.g. "Rotate 90° CW"
794 |
795 | var name = data.exif.getName(0x0112) // "Orientation"
796 |
797 | // A map of all parsed tags with their mapped names/text as keys/values:
798 | var allTags = data.exif.getAll()
799 | ```
800 |
801 | #### Exif Thumbnail
802 |
803 | Example code displaying a thumbnail image embedded into the Exif metadata:
804 |
805 | ```js
806 | loadImage(
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 |
828 | Example code displaying data from the Exif IFD (Image File Directory) that
829 | contains Exif specified TIFF tags:
830 |
831 | ```js
832 | loadImage(
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 |
849 | Example code displaying data from the Exif IFD (Image File Directory) that
850 | contains [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System) info:
851 |
852 | ```js
853 | loadImage(
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 |
870 | Example code displaying data from the Exif IFD (Image File Directory) that
871 | contains Interoperability data:
872 |
873 | ```js
874 | loadImage(
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 |
889 | The 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 |
898 | An example parsing only Orientation, Thumbnail and ExifVersion tags:
899 |
900 | ```js
901 | loadImage.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 |
922 | An example excluding `Exif` `MakerNote` and `GPSInfo`:
923 |
924 | ```js
925 | loadImage.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 |
944 | The Exif parser extension also includes a minimal writer that allows to override
945 | the Exif `Orientation` value in the parsed `imageHead` `ArrayBuffer`:
946 |
947 | ```js
948 | loadImage(
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:**
966 | The Exif writer relies on the Exif tag offsets being available as
967 | `data.exifOffsets` property, which requires that Exif data has been parsed from
968 | the image.
969 | The Exif writer can only change existing values, not add new tags, e.g. it
970 | cannot add an Exif `Orientation` tag for an image that does not have one.
971 |
972 | ### IPTC parser
973 |
974 | If you include the Load Image IPTC Parser extension, the argument passed to the
975 | callback for `parseMetaData` will contain the following additional properties if
976 | IPTC data could be found in the given image:
977 |
978 | - `iptc`: The parsed IPTC tags
979 | - `iptcOffsets`: The parsed IPTC tag offsets
980 |
981 | The `iptc` object stores the parsed IPTC tags:
982 |
983 | ```js
984 | var objectname = data.iptc[5]
985 | ```
986 |
987 | The `iptc` and `iptcOffsets` objects also provide a `get()` method to retrieve
988 | the tag value/offset via the tag's mapped name:
989 |
990 | ```js
991 | var objectname = data.iptc.get('ObjectName')
992 | ```
993 |
994 | By default, only the following names are mapped:
995 |
996 | - `ObjectName`
997 |
998 | If you also include the Load Image IPTC Map library, additional tag mappings
999 | become available, as well as three additional methods:
1000 |
1001 | - `iptc.getText()`
1002 | - `iptc.getName()`
1003 | - `iptc.getAll()`
1004 |
1005 | ```js
1006 | var keywords = data.iptc.getText('Keywords') // e.g.: ['Weather','Sky']
1007 |
1008 | var name = data.iptc.getName(5) // ObjectName
1009 |
1010 | // A map of all parsed tags with their mapped names/text as keys/values:
1011 | var allTags = data.iptc.getAll()
1012 | ```
1013 |
1014 | #### IPTC parser options
1015 |
1016 | The 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 |
1025 | An example parsing only the `ObjectName` tag:
1026 |
1027 | ```js
1028 | loadImage.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 |
1041 | An example excluding `ApplicationRecordVersion` and `ObjectPreviewData`:
1042 |
1043 | ```js
1044 | loadImage.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 |
1060 | The 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).
1071 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/index.js:
--------------------------------------------------------------------------------
1 | /* global module, require */
2 |
3 | module.exports = require('./load-image')
4 |
5 | require('./load-image-scale')
6 | require('./load-image-meta')
7 | require('./load-image-fetch')
8 | require('./load-image-exif')
9 | require('./load-image-exif-map')
10 | require('./load-image-iptc')
11 | require('./load-image-iptc-map')
12 | require('./load-image-orientation')
13 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/load-image-exif-map.js:
--------------------------------------------------------------------------------
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 | })
421 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/load-image-exif.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JavaScript Load Image Exif Parser
3 | * https://github.com/blueimp/JavaScript-Load-Image
4 | *
5 | * Copyright 2013, Sebastian Tschan
6 | * https://blueimp.net
7 | *
8 | * Licensed under the MIT license:
9 | * https://opensource.org/licenses/MIT
10 | */
11 |
12 | /* global define, module, require, DataView */
13 |
14 | /* eslint-disable no-console */
15 |
16 | ;(function (factory) {
17 | 'use strict'
18 | if (typeof define === 'function' && define.amd) {
19 | // Register as an anonymous AMD module:
20 | define(['./load-image', './load-image-meta'], factory)
21 | } else if (typeof module === 'object' && module.exports) {
22 | factory(require('./load-image'), require('./load-image-meta'))
23 | } else {
24 | // Browser globals:
25 | factory(window.loadImage)
26 | }
27 | })(function (loadImage) {
28 | 'use strict'
29 |
30 | /**
31 | * Exif tag map
32 | *
33 | * @name ExifMap
34 | * @class
35 | * @param {number|string} tagCode IFD tag code
36 | */
37 | function ExifMap(tagCode) {
38 | if (tagCode) {
39 | Object.defineProperty(this, 'map', {
40 | value: this.ifds[tagCode].map
41 | })
42 | Object.defineProperty(this, 'tags', {
43 | value: (this.tags && this.tags[tagCode]) || {}
44 | })
45 | }
46 | }
47 |
48 | ExifMap.prototype.map = {
49 | Orientation: 0x0112,
50 | Thumbnail: 'ifd1',
51 | Blob: 0x0201, // Alias for JPEGInterchangeFormat
52 | Exif: 0x8769,
53 | GPSInfo: 0x8825,
54 | Interoperability: 0xa005
55 | }
56 |
57 | ExifMap.prototype.ifds = {
58 | ifd1: { name: 'Thumbnail', map: ExifMap.prototype.map },
59 | 0x8769: { name: 'Exif', map: {} },
60 | 0x8825: { name: 'GPSInfo', map: {} },
61 | 0xa005: { name: 'Interoperability', map: {} }
62 | }
63 |
64 | /**
65 | * Retrieves exif tag value
66 | *
67 | * @param {number|string} id Exif tag code or name
68 | * @returns {object} Exif tag value
69 | */
70 | ExifMap.prototype.get = function (id) {
71 | return this[id] || this[this.map[id]]
72 | }
73 |
74 | /**
75 | * Returns the Exif Thumbnail data as Blob.
76 | *
77 | * @param {DataView} dataView Data view interface
78 | * @param {number} offset Thumbnail data offset
79 | * @param {number} length Thumbnail data length
80 | * @returns {undefined|Blob} Returns the Thumbnail Blob or undefined
81 | */
82 | function getExifThumbnail(dataView, offset, length) {
83 | if (!length) return
84 | if (offset + length > dataView.byteLength) {
85 | console.log('Invalid Exif data: Invalid thumbnail data.')
86 | return
87 | }
88 | return new Blob(
89 | [loadImage.bufferSlice.call(dataView.buffer, offset, offset + length)],
90 | {
91 | type: 'image/jpeg'
92 | }
93 | )
94 | }
95 |
96 | var ExifTagTypes = {
97 | // byte, 8-bit unsigned int:
98 | 1: {
99 | getValue: function (dataView, dataOffset) {
100 | return dataView.getUint8(dataOffset)
101 | },
102 | size: 1
103 | },
104 | // ascii, 8-bit byte:
105 | 2: {
106 | getValue: function (dataView, dataOffset) {
107 | return String.fromCharCode(dataView.getUint8(dataOffset))
108 | },
109 | size: 1,
110 | ascii: true
111 | },
112 | // short, 16 bit int:
113 | 3: {
114 | getValue: function (dataView, dataOffset, littleEndian) {
115 | return dataView.getUint16(dataOffset, littleEndian)
116 | },
117 | size: 2
118 | },
119 | // long, 32 bit int:
120 | 4: {
121 | getValue: function (dataView, dataOffset, littleEndian) {
122 | return dataView.getUint32(dataOffset, littleEndian)
123 | },
124 | size: 4
125 | },
126 | // rational = two long values, first is numerator, second is denominator:
127 | 5: {
128 | getValue: function (dataView, dataOffset, littleEndian) {
129 | return (
130 | dataView.getUint32(dataOffset, littleEndian) /
131 | dataView.getUint32(dataOffset + 4, littleEndian)
132 | )
133 | },
134 | size: 8
135 | },
136 | // slong, 32 bit signed int:
137 | 9: {
138 | getValue: function (dataView, dataOffset, littleEndian) {
139 | return dataView.getInt32(dataOffset, littleEndian)
140 | },
141 | size: 4
142 | },
143 | // srational, two slongs, first is numerator, second is denominator:
144 | 10: {
145 | getValue: function (dataView, dataOffset, littleEndian) {
146 | return (
147 | dataView.getInt32(dataOffset, littleEndian) /
148 | dataView.getInt32(dataOffset + 4, littleEndian)
149 | )
150 | },
151 | size: 8
152 | }
153 | }
154 | // undefined, 8-bit byte, value depending on field:
155 | ExifTagTypes[7] = ExifTagTypes[1]
156 |
157 | /**
158 | * Returns Exif tag value.
159 | *
160 | * @param {DataView} dataView Data view interface
161 | * @param {number} tiffOffset TIFF offset
162 | * @param {number} offset Tag offset
163 | * @param {number} type Tag type
164 | * @param {number} length Tag length
165 | * @param {boolean} littleEndian Little endian encoding
166 | * @returns {object} Tag value
167 | */
168 | function getExifValue(
169 | dataView,
170 | tiffOffset,
171 | offset,
172 | type,
173 | length,
174 | littleEndian
175 | ) {
176 | var tagType = ExifTagTypes[type]
177 | var tagSize
178 | var dataOffset
179 | var values
180 | var i
181 | var str
182 | var c
183 | if (!tagType) {
184 | console.log('Invalid Exif data: Invalid tag type.')
185 | return
186 | }
187 | tagSize = tagType.size * length
188 | // Determine if the value is contained in the dataOffset bytes,
189 | // or if the value at the dataOffset is a pointer to the actual data:
190 | dataOffset =
191 | tagSize > 4
192 | ? tiffOffset + dataView.getUint32(offset + 8, littleEndian)
193 | : offset + 8
194 | if (dataOffset + tagSize > dataView.byteLength) {
195 | console.log('Invalid Exif data: Invalid data offset.')
196 | return
197 | }
198 | if (length === 1) {
199 | return tagType.getValue(dataView, dataOffset, littleEndian)
200 | }
201 | values = []
202 | for (i = 0; i < length; i += 1) {
203 | values[i] = tagType.getValue(
204 | dataView,
205 | dataOffset + i * tagType.size,
206 | littleEndian
207 | )
208 | }
209 | if (tagType.ascii) {
210 | str = ''
211 | // Concatenate the chars:
212 | for (i = 0; i < values.length; i += 1) {
213 | c = values[i]
214 | // Ignore the terminating NULL byte(s):
215 | if (c === '\u0000') {
216 | break
217 | }
218 | str += c
219 | }
220 | return str
221 | }
222 | return values
223 | }
224 |
225 | /**
226 | * Determines if the given tag should be included.
227 | *
228 | * @param {object} includeTags Map of tags to include
229 | * @param {object} excludeTags Map of tags to exclude
230 | * @param {number|string} tagCode Tag code to check
231 | * @returns {boolean} True if the tag should be included
232 | */
233 | function shouldIncludeTag(includeTags, excludeTags, tagCode) {
234 | return (
235 | (!includeTags || includeTags[tagCode]) &&
236 | (!excludeTags || excludeTags[tagCode] !== true)
237 | )
238 | }
239 |
240 | /**
241 | * Parses Exif tags.
242 | *
243 | * @param {DataView} dataView Data view interface
244 | * @param {number} tiffOffset TIFF offset
245 | * @param {number} dirOffset Directory offset
246 | * @param {boolean} littleEndian Little endian encoding
247 | * @param {ExifMap} tags Map to store parsed exif tags
248 | * @param {ExifMap} tagOffsets Map to store parsed exif tag offsets
249 | * @param {object} includeTags Map of tags to include
250 | * @param {object} excludeTags Map of tags to exclude
251 | * @returns {number} Next directory offset
252 | */
253 | function parseExifTags(
254 | dataView,
255 | tiffOffset,
256 | dirOffset,
257 | littleEndian,
258 | tags,
259 | tagOffsets,
260 | includeTags,
261 | excludeTags
262 | ) {
263 | var tagsNumber, dirEndOffset, i, tagOffset, tagNumber, tagValue
264 | if (dirOffset + 6 > dataView.byteLength) {
265 | console.log('Invalid Exif data: Invalid directory offset.')
266 | return
267 | }
268 | tagsNumber = dataView.getUint16(dirOffset, littleEndian)
269 | dirEndOffset = dirOffset + 2 + 12 * tagsNumber
270 | if (dirEndOffset + 4 > dataView.byteLength) {
271 | console.log('Invalid Exif data: Invalid directory size.')
272 | return
273 | }
274 | for (i = 0; i < tagsNumber; i += 1) {
275 | tagOffset = dirOffset + 2 + 12 * i
276 | tagNumber = dataView.getUint16(tagOffset, littleEndian)
277 | if (!shouldIncludeTag(includeTags, excludeTags, tagNumber)) continue
278 | tagValue = getExifValue(
279 | dataView,
280 | tiffOffset,
281 | tagOffset,
282 | dataView.getUint16(tagOffset + 2, littleEndian), // tag type
283 | dataView.getUint32(tagOffset + 4, littleEndian), // tag length
284 | littleEndian
285 | )
286 | tags[tagNumber] = tagValue
287 | if (tagOffsets) {
288 | tagOffsets[tagNumber] = tagOffset
289 | }
290 | }
291 | // Return the offset to the next directory:
292 | return dataView.getUint32(dirEndOffset, littleEndian)
293 | }
294 |
295 | /**
296 | * Parses tags in a given IFD (Image File Directory).
297 | *
298 | * @param {object} data Data object to store exif tags and offsets
299 | * @param {number|string} tagCode IFD tag code
300 | * @param {DataView} dataView Data view interface
301 | * @param {number} tiffOffset TIFF offset
302 | * @param {boolean} littleEndian Little endian encoding
303 | * @param {object} includeTags Map of tags to include
304 | * @param {object} excludeTags Map of tags to exclude
305 | */
306 | function parseExifIFD(
307 | data,
308 | tagCode,
309 | dataView,
310 | tiffOffset,
311 | littleEndian,
312 | includeTags,
313 | excludeTags
314 | ) {
315 | var dirOffset = data.exif[tagCode]
316 | if (dirOffset) {
317 | data.exif[tagCode] = new ExifMap(tagCode)
318 | if (data.exifOffsets) {
319 | data.exifOffsets[tagCode] = new ExifMap(tagCode)
320 | }
321 | parseExifTags(
322 | dataView,
323 | tiffOffset,
324 | tiffOffset + dirOffset,
325 | littleEndian,
326 | data.exif[tagCode],
327 | data.exifOffsets && data.exifOffsets[tagCode],
328 | includeTags && includeTags[tagCode],
329 | excludeTags && excludeTags[tagCode]
330 | )
331 | }
332 | }
333 |
334 | loadImage.parseExifData = function (dataView, offset, length, data, options) {
335 | if (options.disableExif) {
336 | return
337 | }
338 | var includeTags = options.includeExifTags
339 | var excludeTags = options.excludeExifTags || {
340 | 0x8769: {
341 | // ExifIFDPointer
342 | 0x927c: true // MakerNote
343 | }
344 | }
345 | var tiffOffset = offset + 10
346 | var littleEndian
347 | var dirOffset
348 | var thumbnailIFD
349 | // Check for the ASCII code for "Exif" (0x45786966):
350 | if (dataView.getUint32(offset + 4) !== 0x45786966) {
351 | // No Exif data, might be XMP data instead
352 | return
353 | }
354 | if (tiffOffset + 8 > dataView.byteLength) {
355 | console.log('Invalid Exif data: Invalid segment size.')
356 | return
357 | }
358 | // Check for the two null bytes:
359 | if (dataView.getUint16(offset + 8) !== 0x0000) {
360 | console.log('Invalid Exif data: Missing byte alignment offset.')
361 | return
362 | }
363 | // Check the byte alignment:
364 | switch (dataView.getUint16(tiffOffset)) {
365 | case 0x4949:
366 | littleEndian = true
367 | break
368 | case 0x4d4d:
369 | littleEndian = false
370 | break
371 | default:
372 | console.log('Invalid Exif data: Invalid byte alignment marker.')
373 | return
374 | }
375 | // Check for the TIFF tag marker (0x002A):
376 | if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002a) {
377 | console.log('Invalid Exif data: Missing TIFF marker.')
378 | return
379 | }
380 | // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
381 | dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)
382 | // Create the exif object to store the tags:
383 | data.exif = new ExifMap()
384 | if (!options.disableExifOffsets) {
385 | data.exifOffsets = new ExifMap()
386 | data.exifTiffOffset = tiffOffset
387 | data.exifLittleEndian = littleEndian
388 | }
389 | // Parse the tags of the main image directory (IFD0) and retrieve the
390 | // offset to the next directory (IFD1), usually the thumbnail directory:
391 | dirOffset = parseExifTags(
392 | dataView,
393 | tiffOffset,
394 | tiffOffset + dirOffset,
395 | littleEndian,
396 | data.exif,
397 | data.exifOffsets,
398 | includeTags,
399 | excludeTags
400 | )
401 | if (dirOffset && shouldIncludeTag(includeTags, excludeTags, 'ifd1')) {
402 | data.exif.ifd1 = dirOffset
403 | if (data.exifOffsets) {
404 | data.exifOffsets.ifd1 = tiffOffset + dirOffset
405 | }
406 | }
407 | Object.keys(data.exif.ifds).forEach(function (tagCode) {
408 | parseExifIFD(
409 | data,
410 | tagCode,
411 | dataView,
412 | tiffOffset,
413 | littleEndian,
414 | includeTags,
415 | excludeTags
416 | )
417 | })
418 | thumbnailIFD = data.exif.ifd1
419 | // Check for JPEG Thumbnail offset and data length:
420 | if (thumbnailIFD && thumbnailIFD[0x0201]) {
421 | thumbnailIFD[0x0201] = getExifThumbnail(
422 | dataView,
423 | tiffOffset + thumbnailIFD[0x0201],
424 | thumbnailIFD[0x0202] // Thumbnail data length
425 | )
426 | }
427 | }
428 |
429 | // Registers the Exif parser for the APP1 JPEG metadata segment:
430 | loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)
431 |
432 | loadImage.exifWriters = {
433 | // Orientation writer:
434 | 0x0112: function (buffer, data, value) {
435 | var orientationOffset = data.exifOffsets[0x0112]
436 | if (!orientationOffset) return buffer
437 | var view = new DataView(buffer, orientationOffset + 8, 2)
438 | view.setUint16(0, value, data.exifLittleEndian)
439 | return buffer
440 | }
441 | }
442 |
443 | loadImage.writeExifData = function (buffer, data, id, value) {
444 | return loadImage.exifWriters[data.exif.map[id]](buffer, data, value)
445 | }
446 |
447 | loadImage.ExifMap = ExifMap
448 |
449 | // Adds the following properties to the parseMetaData callback data:
450 | // - exif: The parsed Exif tags
451 | // - exifOffsets: The parsed Exif tag offsets
452 | // - exifTiffOffset: TIFF header offset (used for offset pointers)
453 | // - exifLittleEndian: little endian order if true, big endian if false
454 |
455 | // Adds the following options to the parseMetaData method:
456 | // - disableExif: Disables Exif parsing when true.
457 | // - disableExifOffsets: Disables storing Exif tag offsets when true.
458 | // - includeExifTags: A map of Exif tags to include for parsing.
459 | // - excludeExifTags: A map of Exif tags to exclude from parsing.
460 | })
461 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/load-image-fetch.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JavaScript Load Image Fetch
3 | * https://github.com/blueimp/JavaScript-Load-Image
4 | *
5 | * Copyright 2017, Sebastian Tschan
6 | * https://blueimp.net
7 | *
8 | * Licensed under the MIT license:
9 | * https://opensource.org/licenses/MIT
10 | */
11 |
12 | /* global define, module, require, Promise */
13 |
14 | ;(function (factory) {
15 | 'use strict'
16 | if (typeof define === 'function' && define.amd) {
17 | // Register as an anonymous AMD module:
18 | define(['./load-image'], factory)
19 | } else if (typeof module === 'object' && module.exports) {
20 | factory(require('./load-image'))
21 | } else {
22 | // Browser globals:
23 | factory(window.loadImage)
24 | }
25 | })(function (loadImage) {
26 | 'use strict'
27 |
28 | var global = loadImage.global
29 |
30 | if (
31 | global.fetch &&
32 | global.Request &&
33 | global.Response &&
34 | global.Response.prototype.blob
35 | ) {
36 | loadImage.fetchBlob = function (url, callback, options) {
37 | /**
38 | * Fetch response handler.
39 | *
40 | * @param {Response} response Fetch response
41 | * @returns {Blob} Fetched Blob.
42 | */
43 | function responseHandler(response) {
44 | return response.blob()
45 | }
46 | if (global.Promise && typeof callback !== 'function') {
47 | return fetch(new Request(url, callback)).then(responseHandler)
48 | }
49 | fetch(new Request(url, options))
50 | .then(responseHandler)
51 | .then(callback)
52 | [
53 | // Avoid parsing error in IE<9, where catch is a reserved word.
54 | // eslint-disable-next-line dot-notation
55 | 'catch'
56 | ](function (err) {
57 | callback(null, err)
58 | })
59 | }
60 | } else if (
61 | global.XMLHttpRequest &&
62 | // https://xhr.spec.whatwg.org/#the-responsetype-attribute
63 | new XMLHttpRequest().responseType === ''
64 | ) {
65 | loadImage.fetchBlob = function (url, callback, options) {
66 | /**
67 | * Promise executor
68 | *
69 | * @param {Function} resolve Resolution function
70 | * @param {Function} reject Rejection function
71 | */
72 | function executor(resolve, reject) {
73 | options = options || {} // eslint-disable-line no-param-reassign
74 | var req = new XMLHttpRequest()
75 | req.open(options.method || 'GET', url)
76 | if (options.headers) {
77 | Object.keys(options.headers).forEach(function (key) {
78 | req.setRequestHeader(key, options.headers[key])
79 | })
80 | }
81 | req.withCredentials = options.credentials === 'include'
82 | req.responseType = 'blob'
83 | req.onload = function () {
84 | resolve(req.response)
85 | }
86 | req.onerror = req.onabort = req.ontimeout = function (err) {
87 | if (resolve === reject) {
88 | // Not using Promises
89 | reject(null, err)
90 | } else {
91 | reject(err)
92 | }
93 | }
94 | req.send(options.body)
95 | }
96 | if (global.Promise && typeof callback !== 'function') {
97 | options = callback // eslint-disable-line no-param-reassign
98 | return new Promise(executor)
99 | }
100 | return executor(callback, callback)
101 | }
102 | }
103 | })
104 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/load-image-iptc-map.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JavaScript Load Image IPTC Map
3 | * https://github.com/blueimp/JavaScript-Load-Image
4 | *
5 | * Copyright 2013, Sebastian Tschan
6 | * Copyright 2018, Dave Bevan
7 | *
8 | * IPTC tags mapping based on
9 | * https://iptc.org/standards/photo-metadata
10 | * https://exiftool.org/TagNames/IPTC.html
11 | *
12 | * Licensed under the MIT license:
13 | * https://opensource.org/licenses/MIT
14 | */
15 |
16 | /* global define, module, require */
17 |
18 | ;(function (factory) {
19 | 'use strict'
20 | if (typeof define === 'function' && define.amd) {
21 | // Register as an anonymous AMD module:
22 | define(['./load-image', './load-image-iptc'], factory)
23 | } else if (typeof module === 'object' && module.exports) {
24 | factory(require('./load-image'), require('./load-image-iptc'))
25 | } else {
26 | // Browser globals:
27 | factory(window.loadImage)
28 | }
29 | })(function (loadImage) {
30 | 'use strict'
31 |
32 | var IptcMapProto = loadImage.IptcMap.prototype
33 |
34 | IptcMapProto.tags = {
35 | 0: 'ApplicationRecordVersion',
36 | 3: 'ObjectTypeReference',
37 | 4: 'ObjectAttributeReference',
38 | 5: 'ObjectName',
39 | 7: 'EditStatus',
40 | 8: 'EditorialUpdate',
41 | 10: 'Urgency',
42 | 12: 'SubjectReference',
43 | 15: 'Category',
44 | 20: 'SupplementalCategories',
45 | 22: 'FixtureIdentifier',
46 | 25: 'Keywords',
47 | 26: 'ContentLocationCode',
48 | 27: 'ContentLocationName',
49 | 30: 'ReleaseDate',
50 | 35: 'ReleaseTime',
51 | 37: 'ExpirationDate',
52 | 38: 'ExpirationTime',
53 | 40: 'SpecialInstructions',
54 | 42: 'ActionAdvised',
55 | 45: 'ReferenceService',
56 | 47: 'ReferenceDate',
57 | 50: 'ReferenceNumber',
58 | 55: 'DateCreated',
59 | 60: 'TimeCreated',
60 | 62: 'DigitalCreationDate',
61 | 63: 'DigitalCreationTime',
62 | 65: 'OriginatingProgram',
63 | 70: 'ProgramVersion',
64 | 75: 'ObjectCycle',
65 | 80: 'Byline',
66 | 85: 'BylineTitle',
67 | 90: 'City',
68 | 92: 'Sublocation',
69 | 95: 'State',
70 | 100: 'CountryCode',
71 | 101: 'Country',
72 | 103: 'OriginalTransmissionReference',
73 | 105: 'Headline',
74 | 110: 'Credit',
75 | 115: 'Source',
76 | 116: 'CopyrightNotice',
77 | 118: 'Contact',
78 | 120: 'Caption',
79 | 121: 'LocalCaption',
80 | 122: 'Writer',
81 | 125: 'RasterizedCaption',
82 | 130: 'ImageType',
83 | 131: 'ImageOrientation',
84 | 135: 'LanguageIdentifier',
85 | 150: 'AudioType',
86 | 151: 'AudioSamplingRate',
87 | 152: 'AudioSamplingResolution',
88 | 153: 'AudioDuration',
89 | 154: 'AudioOutcue',
90 | 184: 'JobID',
91 | 185: 'MasterDocumentID',
92 | 186: 'ShortDocumentID',
93 | 187: 'UniqueDocumentID',
94 | 188: 'OwnerID',
95 | 200: 'ObjectPreviewFileFormat',
96 | 201: 'ObjectPreviewFileVersion',
97 | 202: 'ObjectPreviewData',
98 | 221: 'Prefs',
99 | 225: 'ClassifyState',
100 | 228: 'SimilarityIndex',
101 | 230: 'DocumentNotes',
102 | 231: 'DocumentHistory',
103 | 232: 'ExifCameraInfo',
104 | 255: 'CatalogSets'
105 | }
106 |
107 | IptcMapProto.stringValues = {
108 | 10: {
109 | 0: '0 (reserved)',
110 | 1: '1 (most urgent)',
111 | 2: '2',
112 | 3: '3',
113 | 4: '4',
114 | 5: '5 (normal urgency)',
115 | 6: '6',
116 | 7: '7',
117 | 8: '8 (least urgent)',
118 | 9: '9 (user-defined priority)'
119 | },
120 | 75: {
121 | a: 'Morning',
122 | b: 'Both Morning and Evening',
123 | p: 'Evening'
124 | },
125 | 131: {
126 | L: 'Landscape',
127 | P: 'Portrait',
128 | S: 'Square'
129 | }
130 | }
131 |
132 | IptcMapProto.getText = function (id) {
133 | var value = this.get(id)
134 | var tagCode = this.map[id]
135 | var stringValue = this.stringValues[tagCode]
136 | if (stringValue) return stringValue[value]
137 | return String(value)
138 | }
139 |
140 | IptcMapProto.getAll = function () {
141 | var map = {}
142 | var prop
143 | var name
144 | for (prop in this) {
145 | if (Object.prototype.hasOwnProperty.call(this, prop)) {
146 | name = this.tags[prop]
147 | if (name) map[name] = this.getText(name)
148 | }
149 | }
150 | return map
151 | }
152 |
153 | IptcMapProto.getName = function (tagCode) {
154 | return this.tags[tagCode]
155 | }
156 |
157 | // Extend the map of tag names to tag codes:
158 | ;(function () {
159 | var tags = IptcMapProto.tags
160 | var map = IptcMapProto.map || {}
161 | var prop
162 | // Map the tag names to tags:
163 | for (prop in tags) {
164 | if (Object.prototype.hasOwnProperty.call(tags, prop)) {
165 | map[tags[prop]] = Number(prop)
166 | }
167 | }
168 | })()
169 | })
170 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/load-image-iptc.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JavaScript Load Image IPTC Parser
3 | * https://github.com/blueimp/JavaScript-Load-Image
4 | *
5 | * Copyright 2013, Sebastian Tschan
6 | * Copyright 2018, Dave Bevan
7 | * https://blueimp.net
8 | *
9 | * Licensed under the MIT license:
10 | * https://opensource.org/licenses/MIT
11 | */
12 |
13 | /* global define, module, require, DataView */
14 |
15 | ;(function (factory) {
16 | 'use strict'
17 | if (typeof define === 'function' && define.amd) {
18 | // Register as an anonymous AMD module:
19 | define(['./load-image', './load-image-meta'], factory)
20 | } else if (typeof module === 'object' && module.exports) {
21 | factory(require('./load-image'), require('./load-image-meta'))
22 | } else {
23 | // Browser globals:
24 | factory(window.loadImage)
25 | }
26 | })(function (loadImage) {
27 | 'use strict'
28 |
29 | /**
30 | * IPTC tag map
31 | *
32 | * @name IptcMap
33 | * @class
34 | */
35 | function IptcMap() {}
36 |
37 | IptcMap.prototype.map = {
38 | ObjectName: 5
39 | }
40 |
41 | IptcMap.prototype.types = {
42 | 0: 'Uint16', // ApplicationRecordVersion
43 | 200: 'Uint16', // ObjectPreviewFileFormat
44 | 201: 'Uint16', // ObjectPreviewFileVersion
45 | 202: 'binary' // ObjectPreviewData
46 | }
47 |
48 | /**
49 | * Retrieves IPTC tag value
50 | *
51 | * @param {number|string} id IPTC tag code or name
52 | * @returns {object} IPTC tag value
53 | */
54 | IptcMap.prototype.get = function (id) {
55 | return this[id] || this[this.map[id]]
56 | }
57 |
58 | /**
59 | * Retrieves string for the given DataView and range
60 | *
61 | * @param {DataView} dataView Data view interface
62 | * @param {number} offset Offset start
63 | * @param {number} length Offset length
64 | * @returns {string} String value
65 | */
66 | function getStringValue(dataView, offset, length) {
67 | var outstr = ''
68 | var end = offset + length
69 | for (var n = offset; n < end; n += 1) {
70 | outstr += String.fromCharCode(dataView.getUint8(n))
71 | }
72 | return outstr
73 | }
74 |
75 | /**
76 | * Retrieves tag value for the given DataView and range
77 | *
78 | * @param {number} tagCode tag code
79 | * @param {IptcMap} map IPTC tag map
80 | * @param {DataView} dataView Data view interface
81 | * @param {number} offset Range start
82 | * @param {number} length Range length
83 | * @returns {object} Tag value
84 | */
85 | function getTagValue(tagCode, map, dataView, offset, length) {
86 | if (map.types[tagCode] === 'binary') {
87 | return new Blob([dataView.buffer.slice(offset, offset + length)])
88 | }
89 | if (map.types[tagCode] === 'Uint16') {
90 | return dataView.getUint16(offset)
91 | }
92 | return getStringValue(dataView, offset, length)
93 | }
94 |
95 | /**
96 | * Combines IPTC value with existing ones.
97 | *
98 | * @param {object} value Existing IPTC field value
99 | * @param {object} newValue New IPTC field value
100 | * @returns {object} Resulting IPTC field value
101 | */
102 | function combineTagValues(value, newValue) {
103 | if (value === undefined) return newValue
104 | if (value instanceof Array) {
105 | value.push(newValue)
106 | return value
107 | }
108 | return [value, newValue]
109 | }
110 |
111 | /**
112 | * Parses IPTC tags.
113 | *
114 | * @param {DataView} dataView Data view interface
115 | * @param {number} segmentOffset Segment offset
116 | * @param {number} segmentLength Segment length
117 | * @param {object} data Data export object
118 | * @param {object} includeTags Map of tags to include
119 | * @param {object} excludeTags Map of tags to exclude
120 | */
121 | function parseIptcTags(
122 | dataView,
123 | segmentOffset,
124 | segmentLength,
125 | data,
126 | includeTags,
127 | excludeTags
128 | ) {
129 | var value, tagSize, tagCode
130 | var segmentEnd = segmentOffset + segmentLength
131 | var offset = segmentOffset
132 | while (offset < segmentEnd) {
133 | if (
134 | dataView.getUint8(offset) === 0x1c && // tag marker
135 | dataView.getUint8(offset + 1) === 0x02 // record number, only handles v2
136 | ) {
137 | tagCode = dataView.getUint8(offset + 2)
138 | if (
139 | (!includeTags || includeTags[tagCode]) &&
140 | (!excludeTags || !excludeTags[tagCode])
141 | ) {
142 | tagSize = dataView.getInt16(offset + 3)
143 | value = getTagValue(tagCode, data.iptc, dataView, offset + 5, tagSize)
144 | data.iptc[tagCode] = combineTagValues(data.iptc[tagCode], value)
145 | if (data.iptcOffsets) {
146 | data.iptcOffsets[tagCode] = offset
147 | }
148 | }
149 | }
150 | offset += 1
151 | }
152 | }
153 |
154 | /**
155 | * Tests if field segment starts at offset.
156 | *
157 | * @param {DataView} dataView Data view interface
158 | * @param {number} offset Segment offset
159 | * @returns {boolean} True if '8BIM' exists at offset
160 | */
161 | function isSegmentStart(dataView, offset) {
162 | return (
163 | dataView.getUint32(offset) === 0x3842494d && // Photoshop segment start
164 | dataView.getUint16(offset + 4) === 0x0404 // IPTC segment start
165 | )
166 | }
167 |
168 | /**
169 | * Returns header length.
170 | *
171 | * @param {DataView} dataView Data view interface
172 | * @param {number} offset Segment offset
173 | * @returns {number} Header length
174 | */
175 | function getHeaderLength(dataView, offset) {
176 | var length = dataView.getUint8(offset + 7)
177 | if (length % 2 !== 0) length += 1
178 | // Check for pre photoshop 6 format
179 | if (length === 0) {
180 | // Always 4
181 | length = 4
182 | }
183 | return length
184 | }
185 |
186 | loadImage.parseIptcData = function (dataView, offset, length, data, options) {
187 | if (options.disableIptc) {
188 | return
189 | }
190 | var markerLength = offset + length
191 | while (offset + 8 < markerLength) {
192 | if (isSegmentStart(dataView, offset)) {
193 | var headerLength = getHeaderLength(dataView, offset)
194 | var segmentOffset = offset + 8 + headerLength
195 | if (segmentOffset > markerLength) {
196 | // eslint-disable-next-line no-console
197 | console.log('Invalid IPTC data: Invalid segment offset.')
198 | break
199 | }
200 | var segmentLength = dataView.getUint16(offset + 6 + headerLength)
201 | if (offset + segmentLength > markerLength) {
202 | // eslint-disable-next-line no-console
203 | console.log('Invalid IPTC data: Invalid segment size.')
204 | break
205 | }
206 | // Create the iptc object to store the tags:
207 | data.iptc = new IptcMap()
208 | if (!options.disableIptcOffsets) {
209 | data.iptcOffsets = new IptcMap()
210 | }
211 | parseIptcTags(
212 | dataView,
213 | segmentOffset,
214 | segmentLength,
215 | data,
216 | options.includeIptcTags,
217 | options.excludeIptcTags || { 202: true } // ObjectPreviewData
218 | )
219 | return
220 | }
221 | // eslint-disable-next-line no-param-reassign
222 | offset += 1
223 | }
224 | }
225 |
226 | // Registers this IPTC parser for the APP13 JPEG metadata segment:
227 | loadImage.metaDataParsers.jpeg[0xffed].push(loadImage.parseIptcData)
228 |
229 | loadImage.IptcMap = IptcMap
230 |
231 | // Adds the following properties to the parseMetaData callback data:
232 | // - iptc: The iptc tags, parsed by the parseIptcData method
233 |
234 | // Adds the following options to the parseMetaData method:
235 | // - disableIptc: Disables IPTC parsing when true.
236 | // - disableIptcOffsets: Disables storing IPTC tag offsets when true.
237 | // - includeIptcTags: A map of IPTC tags to include for parsing.
238 | // - excludeIptcTags: A map of IPTC tags to exclude from parsing.
239 | })
240 |
--------------------------------------------------------------------------------
/node_modules/blueimp-load-image/js/load-image-meta.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JavaScript Load Image Meta
3 | * https://github.com/blueimp/JavaScript-Load-Image
4 | *
5 | * Copyright 2013, Sebastian Tschan
6 | * https://blueimp.net
7 | *
8 | * Image metadata handling implementation
9 | * based on the help and contribution of
10 | * Achim Stöhr.
11 | *
12 | * Licensed under the MIT license:
13 | * https://opensource.org/licenses/MIT
14 | */
15 |
16 | /* global define, module, require, Promise, DataView, Uint8Array, ArrayBuffer */
17 |
18 | ;(function (factory) {
19 | 'use strict'
20 | if (typeof define === 'function' && define.amd) {
21 | // Register as an anonymous AMD module:
22 | define(['./load-image'], factory)
23 | } else if (typeof module === 'object' && module.exports) {
24 | factory(require('./load-image'))
25 | } else {
26 | // Browser globals:
27 | factory(window.loadImage)
28 | }
29 | })(function (loadImage) {
30 | 'use strict'
31 |
32 | var global = loadImage.global
33 | var originalTransform = loadImage.transform
34 |
35 | var blobSlice =
36 | global.Blob &&
37 | (Blob.prototype.slice ||
38 | Blob.prototype.webkitSlice ||
39 | Blob.prototype.mozSlice)
40 |
41 | var bufferSlice =
42 | (global.ArrayBuffer && ArrayBuffer.prototype.slice) ||
43 | function (begin, end) {
44 | // Polyfill for IE10, which does not support ArrayBuffer.slice
45 | // eslint-disable-next-line no-param-reassign
46 | end = end || this.byteLength - begin
47 | var arr1 = new Uint8Array(this, begin, end)
48 | var arr2 = new Uint8Array(end)
49 | arr2.set(arr1)
50 | return arr2.buffer
51 | }
52 |
53 | var metaDataParsers = {
54 | jpeg: {
55 | 0xffe1: [], // APP1 marker
56 | 0xffed: [] // APP13 marker
57 | }
58 | }
59 |
60 | /**
61 | * Parses image metadata and calls the callback with an object argument
62 | * with the following property:
63 | * - imageHead: The complete image head as ArrayBuffer
64 | * The options argument accepts an object and supports the following
65 | * properties:
66 | * - maxMetaDataSize: Defines the maximum number of bytes to parse.
67 | * - disableImageHead: Disables creating the imageHead property.
68 | *
69 | * @param {Blob} file Blob object
70 | * @param {Function} [callback] Callback function
71 | * @param {object} [options] Parsing options
72 | * @param {object} [data] Result data object
73 | * @returns {Promise