compressorjs 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright 2018-present Chen Fengyuan
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all 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,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2018-present Chen Fengyuan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all 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,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  [![Coverage Status](https://img.shields.io/codecov/c/github/fengyuanchen/compressorjs.svg)](https://codecov.io/gh/fengyuanchen/compressorjs) [![Downloads](https://img.shields.io/npm/dm/compressorjs.svg)](https://www.npmjs.com/package/compressorjs) [![Version](https://img.shields.io/npm/v/compressorjs.svg)](https://www.npmjs.com/package/compressorjs) [![Gzip Size](https://img.shields.io/bundlephobia/minzip/compressorjs.svg)](https://unpkg.com/compressorjs/dist/compressor.common.js)
4
4
 
5
- > JavaScript image compressor. Uses the Browser's native [canvas.toBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) API to do the compression work, which means it is **lossy compression**, **asynchronous**, and has **different compression effects in different browsers**. Generally use this to precompress a image on the client side before uploading it.
5
+ > JavaScript image compressor. Uses the Browser's native [HTMLCanvasElement.toBlob()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) method to do the compression work, which means it is **lossy compression**, **asynchronous**, and has **different compression effects in different browsers**. Generally use this to precompress a image on the client side before uploading it.
6
6
 
7
7
  - [Website](https://fengyuanchen.github.io/compressorjs)
8
8
 
9
9
  ## Table of contents
10
10
 
11
- - [Main](#main)
11
+ - [Main Files](#main-files)
12
12
  - [Getting started](#getting-started)
13
13
  - [Options](#options)
14
14
  - [Methods](#methods)
@@ -18,7 +18,7 @@
18
18
  - [Versioning](#versioning)
19
19
  - [License](#license)
20
20
 
21
- ## Main
21
+ ## Main Files
22
22
 
23
23
  ```text
24
24
  dist/
@@ -204,7 +204,7 @@ The quality of the output image. It must be a number between `0` and `1`. If thi
204
204
 
205
205
  **Note:** This option only available for `image/jpeg` and `image/webp` images.
206
206
 
207
- > Check out [canvas.toBlob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) for more detail.
207
+ > Check out the documentation of the [HTMLCanvasElement.toBlob()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) method for more detail.
208
208
 
209
209
  **Examples**:
210
210
 
@@ -222,19 +222,24 @@ The quality of the output image. It must be a number between `0` and `1`. If thi
222
222
 
223
223
  - Type: `string`
224
224
  - Default: `'auto'`
225
+ - Options: `"auto"`, `"image/png"`, `"image/jpeg"`, and `"image/webp"`.
225
226
 
226
227
  The mime type of the output image. By default, the original mime type of the source image file will be used.
227
228
 
229
+ > **Note:** Safari does not support `mimeType` conversion to `"image/webp"`. For more details, see the [browser compatibility of the `HTMLCanvasElement.toBlob()` method](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#browser_compatibility).
230
+
228
231
  ### convertTypes
229
232
 
230
233
  - Type: `Array` or `string` (multiple types should be separated by commas)
231
- - Default: `['image/png']`
234
+ - Default: `["image/png"]`
232
235
  - Examples:
233
- - `['image/png', 'image/webp']`
234
- - `'image/png,image/webp'`
236
+ - `["image/png", "image/webp"]`
237
+ - `"image/png,image/webp"`
235
238
 
236
239
  Files whose file type is included in this list, and whose file size exceeds the `convertSize` value will be converted to JPEGs.
237
240
 
241
+ > For image file type support, see the [Image file type and format guide](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types).
242
+
238
243
  ### convertSize
239
244
 
240
245
  - Type: `number`
@@ -1,99 +1,80 @@
1
1
  /*!
2
- * Compressor.js v1.2.1
2
+ * Compressor.js v1.3.0
3
3
  * https://fengyuanchen.github.io/compressorjs
4
4
  *
5
5
  * Copyright 2018-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2023-02-28T14:09:41.732Z
8
+ * Date: 2026-04-06T07:12:45.816Z
9
9
  */
10
10
 
11
11
  'use strict';
12
12
 
13
- function ownKeys(object, enumerableOnly) {
14
- var keys = Object.keys(object);
15
- if (Object.getOwnPropertySymbols) {
16
- var symbols = Object.getOwnPropertySymbols(object);
17
- enumerableOnly && (symbols = symbols.filter(function (sym) {
18
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
19
- })), keys.push.apply(keys, symbols);
20
- }
21
- return keys;
13
+ function _classCallCheck(a, n) {
14
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
22
15
  }
23
- function _objectSpread2(target) {
24
- for (var i = 1; i < arguments.length; i++) {
25
- var source = null != arguments[i] ? arguments[i] : {};
26
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
27
- _defineProperty(target, key, source[key]);
28
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
29
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
30
- });
16
+ function _defineProperties(e, r) {
17
+ for (var t = 0; t < r.length; t++) {
18
+ var o = r[t];
19
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
31
20
  }
32
- return target;
33
21
  }
34
- function _classCallCheck(instance, Constructor) {
35
- if (!(instance instanceof Constructor)) {
36
- throw new TypeError("Cannot call a class as a function");
37
- }
22
+ function _createClass(e, r, t) {
23
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
24
+ writable: !1
25
+ }), e;
38
26
  }
39
- function _defineProperties(target, props) {
40
- for (var i = 0; i < props.length; i++) {
41
- var descriptor = props[i];
42
- descriptor.enumerable = descriptor.enumerable || false;
43
- descriptor.configurable = true;
44
- if ("value" in descriptor) descriptor.writable = true;
45
- Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
46
- }
27
+ function _defineProperty(e, r, t) {
28
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
29
+ value: t,
30
+ enumerable: !0,
31
+ configurable: !0,
32
+ writable: !0
33
+ }) : e[r] = t, e;
47
34
  }
48
- function _createClass(Constructor, protoProps, staticProps) {
49
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
50
- if (staticProps) _defineProperties(Constructor, staticProps);
51
- Object.defineProperty(Constructor, "prototype", {
52
- writable: false
53
- });
54
- return Constructor;
35
+ function _extends() {
36
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
37
+ for (var e = 1; e < arguments.length; e++) {
38
+ var t = arguments[e];
39
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
40
+ }
41
+ return n;
42
+ }, _extends.apply(null, arguments);
55
43
  }
56
- function _defineProperty(obj, key, value) {
57
- key = _toPropertyKey(key);
58
- if (key in obj) {
59
- Object.defineProperty(obj, key, {
60
- value: value,
61
- enumerable: true,
62
- configurable: true,
63
- writable: true
64
- });
65
- } else {
66
- obj[key] = value;
44
+ function ownKeys(e, r) {
45
+ var t = Object.keys(e);
46
+ if (Object.getOwnPropertySymbols) {
47
+ var o = Object.getOwnPropertySymbols(e);
48
+ r && (o = o.filter(function (r) {
49
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
50
+ })), t.push.apply(t, o);
67
51
  }
68
- return obj;
52
+ return t;
69
53
  }
70
- function _extends() {
71
- _extends = Object.assign ? Object.assign.bind() : function (target) {
72
- for (var i = 1; i < arguments.length; i++) {
73
- var source = arguments[i];
74
- for (var key in source) {
75
- if (Object.prototype.hasOwnProperty.call(source, key)) {
76
- target[key] = source[key];
77
- }
78
- }
79
- }
80
- return target;
81
- };
82
- return _extends.apply(this, arguments);
54
+ function _objectSpread2(e) {
55
+ for (var r = 1; r < arguments.length; r++) {
56
+ var t = null != arguments[r] ? arguments[r] : {};
57
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
58
+ _defineProperty(e, r, t[r]);
59
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
60
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
61
+ });
62
+ }
63
+ return e;
83
64
  }
84
- function _toPrimitive(input, hint) {
85
- if (typeof input !== "object" || input === null) return input;
86
- var prim = input[Symbol.toPrimitive];
87
- if (prim !== undefined) {
88
- var res = prim.call(input, hint || "default");
89
- if (typeof res !== "object") return res;
65
+ function _toPrimitive(t, r) {
66
+ if ("object" != typeof t || !t) return t;
67
+ var e = t[Symbol.toPrimitive];
68
+ if (void 0 !== e) {
69
+ var i = e.call(t, r || "default");
70
+ if ("object" != typeof i) return i;
90
71
  throw new TypeError("@@toPrimitive must return a primitive value.");
91
72
  }
92
- return (hint === "string" ? String : Number)(input);
73
+ return ("string" === r ? String : Number)(t);
93
74
  }
94
- function _toPropertyKey(arg) {
95
- var key = _toPrimitive(arg, "string");
96
- return typeof key === "symbol" ? key : String(key);
75
+ function _toPropertyKey(t) {
76
+ var i = _toPrimitive(t, "string");
77
+ return "symbol" == typeof i ? i : i + "";
97
78
  }
98
79
 
99
80
  var canvasToBlob = {exports: {}};
@@ -406,6 +387,49 @@ function getStringFromCharCode(dataView, start, length) {
406
387
  }
407
388
  return str;
408
389
  }
390
+
391
+ /**
392
+ * Check if `canvas.getContext('2d').getImageData` is available,
393
+ * FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode (#137)
394
+ * @link https://github.com/nodeca/pica/blob/master/lib/utils.js
395
+ * @returns {boolean} Returns `true` if it is available, else `false`.
396
+ */
397
+ function isCanvasAvailable() {
398
+ try {
399
+ var canvas = document.createElement('canvas');
400
+ canvas.width = 2;
401
+ canvas.height = 1;
402
+ var context = canvas.getContext('2d');
403
+ if (!context) return false;
404
+
405
+ // Create 2x1 image data containing RGBA values for two pixels
406
+ var imageData = context.createImageData(2, 1);
407
+
408
+ // First pixel: R=12, G=23, B=34, A=255
409
+ imageData.data[0] = 12;
410
+ imageData.data[1] = 23;
411
+ imageData.data[2] = 34;
412
+ imageData.data[3] = 255;
413
+
414
+ // Second pixel: R=45, G=56, B=67, A=255
415
+ imageData.data[4] = 45;
416
+ imageData.data[5] = 56;
417
+ imageData.data[6] = 67;
418
+ imageData.data[7] = 255;
419
+ context.putImageData(imageData, 0, 0);
420
+ var readBack = context.getImageData(0, 0, 2, 1);
421
+
422
+ // Expected pixel data (matching the written values)
423
+ var expected = [12, 23, 34, 255, 45, 56, 67, 255];
424
+
425
+ // Compare element by element to ensure write and read consistency
426
+ return readBack.data.every(function (value, index) {
427
+ return value === expected[index];
428
+ });
429
+ } catch (error) {
430
+ return false;
431
+ }
432
+ }
409
433
  var btoa = WINDOW.btoa;
410
434
 
411
435
  /**
@@ -673,7 +697,7 @@ var Compressor = /*#__PURE__*/function () {
673
697
  this.result = null;
674
698
  this.init();
675
699
  }
676
- _createClass(Compressor, [{
700
+ return _createClass(Compressor, [{
677
701
  key: "init",
678
702
  value: function init() {
679
703
  var _this = this;
@@ -759,10 +783,18 @@ var Compressor = /*#__PURE__*/function () {
759
783
  var file = this.file,
760
784
  image = this.image;
761
785
  image.onload = function () {
762
- _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
763
- naturalWidth: image.naturalWidth,
764
- naturalHeight: image.naturalHeight
765
- }));
786
+ if (isCanvasAvailable()) {
787
+ _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
788
+ naturalWidth: image.naturalWidth,
789
+ naturalHeight: image.naturalHeight
790
+ }));
791
+ } else {
792
+ _this2.done({
793
+ naturalWidth: image.naturalWidth,
794
+ naturalHeight: image.naturalHeight,
795
+ result: null
796
+ });
797
+ }
766
798
  };
767
799
  image.onabort = function () {
768
800
  _this2.fail(new Error('Aborted to load the image.'));
@@ -985,14 +1017,25 @@ var Compressor = /*#__PURE__*/function () {
985
1017
  if (options.strict && !options.retainExif && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
986
1018
  result = file;
987
1019
  } else {
988
- var date = new Date();
989
- result.lastModified = date.getTime();
990
- result.lastModifiedDate = date;
991
- result.name = file.name;
1020
+ var fileName = file.name;
992
1021
 
993
1022
  // Convert the extension to match its type
994
- if (result.name && result.type !== file.type) {
995
- result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1023
+ if (fileName && result.type !== file.type) {
1024
+ fileName = fileName.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1025
+ }
1026
+ try {
1027
+ // Convert the resulting Blob object into a File object for modern browsers.
1028
+ result = new File([result], fileName, {
1029
+ type: result.type
1030
+ });
1031
+ } catch (error) {
1032
+ // Fallback to Blob if the File constructor is not supported.
1033
+ var date = new Date();
1034
+ result.name = fileName;
1035
+
1036
+ // The last modified date is not accurate, but it's better than nothing.
1037
+ result.lastModified = date.getTime();
1038
+ result.lastModifiedDate = date;
996
1039
  }
997
1040
  }
998
1041
  } else {
@@ -1051,7 +1094,6 @@ var Compressor = /*#__PURE__*/function () {
1051
1094
  _extends(DEFAULTS, options);
1052
1095
  }
1053
1096
  }]);
1054
- return Compressor;
1055
1097
  }();
1056
1098
 
1057
1099
  module.exports = Compressor;
@@ -1,97 +1,78 @@
1
1
  /*!
2
- * Compressor.js v1.2.1
2
+ * Compressor.js v1.3.0
3
3
  * https://fengyuanchen.github.io/compressorjs
4
4
  *
5
5
  * Copyright 2018-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2023-02-28T14:09:41.732Z
8
+ * Date: 2026-04-06T07:12:45.816Z
9
9
  */
10
10
 
11
- function ownKeys(object, enumerableOnly) {
12
- var keys = Object.keys(object);
13
- if (Object.getOwnPropertySymbols) {
14
- var symbols = Object.getOwnPropertySymbols(object);
15
- enumerableOnly && (symbols = symbols.filter(function (sym) {
16
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
17
- })), keys.push.apply(keys, symbols);
18
- }
19
- return keys;
11
+ function _classCallCheck(a, n) {
12
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
20
13
  }
21
- function _objectSpread2(target) {
22
- for (var i = 1; i < arguments.length; i++) {
23
- var source = null != arguments[i] ? arguments[i] : {};
24
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
25
- _defineProperty(target, key, source[key]);
26
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
27
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
28
- });
14
+ function _defineProperties(e, r) {
15
+ for (var t = 0; t < r.length; t++) {
16
+ var o = r[t];
17
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
29
18
  }
30
- return target;
31
19
  }
32
- function _classCallCheck(instance, Constructor) {
33
- if (!(instance instanceof Constructor)) {
34
- throw new TypeError("Cannot call a class as a function");
35
- }
20
+ function _createClass(e, r, t) {
21
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
22
+ writable: !1
23
+ }), e;
36
24
  }
37
- function _defineProperties(target, props) {
38
- for (var i = 0; i < props.length; i++) {
39
- var descriptor = props[i];
40
- descriptor.enumerable = descriptor.enumerable || false;
41
- descriptor.configurable = true;
42
- if ("value" in descriptor) descriptor.writable = true;
43
- Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
44
- }
25
+ function _defineProperty(e, r, t) {
26
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
27
+ value: t,
28
+ enumerable: !0,
29
+ configurable: !0,
30
+ writable: !0
31
+ }) : e[r] = t, e;
45
32
  }
46
- function _createClass(Constructor, protoProps, staticProps) {
47
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
48
- if (staticProps) _defineProperties(Constructor, staticProps);
49
- Object.defineProperty(Constructor, "prototype", {
50
- writable: false
51
- });
52
- return Constructor;
33
+ function _extends() {
34
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
35
+ for (var e = 1; e < arguments.length; e++) {
36
+ var t = arguments[e];
37
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
38
+ }
39
+ return n;
40
+ }, _extends.apply(null, arguments);
53
41
  }
54
- function _defineProperty(obj, key, value) {
55
- key = _toPropertyKey(key);
56
- if (key in obj) {
57
- Object.defineProperty(obj, key, {
58
- value: value,
59
- enumerable: true,
60
- configurable: true,
61
- writable: true
62
- });
63
- } else {
64
- obj[key] = value;
42
+ function ownKeys(e, r) {
43
+ var t = Object.keys(e);
44
+ if (Object.getOwnPropertySymbols) {
45
+ var o = Object.getOwnPropertySymbols(e);
46
+ r && (o = o.filter(function (r) {
47
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
48
+ })), t.push.apply(t, o);
65
49
  }
66
- return obj;
50
+ return t;
67
51
  }
68
- function _extends() {
69
- _extends = Object.assign ? Object.assign.bind() : function (target) {
70
- for (var i = 1; i < arguments.length; i++) {
71
- var source = arguments[i];
72
- for (var key in source) {
73
- if (Object.prototype.hasOwnProperty.call(source, key)) {
74
- target[key] = source[key];
75
- }
76
- }
77
- }
78
- return target;
79
- };
80
- return _extends.apply(this, arguments);
52
+ function _objectSpread2(e) {
53
+ for (var r = 1; r < arguments.length; r++) {
54
+ var t = null != arguments[r] ? arguments[r] : {};
55
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
56
+ _defineProperty(e, r, t[r]);
57
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
58
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
59
+ });
60
+ }
61
+ return e;
81
62
  }
82
- function _toPrimitive(input, hint) {
83
- if (typeof input !== "object" || input === null) return input;
84
- var prim = input[Symbol.toPrimitive];
85
- if (prim !== undefined) {
86
- var res = prim.call(input, hint || "default");
87
- if (typeof res !== "object") return res;
63
+ function _toPrimitive(t, r) {
64
+ if ("object" != typeof t || !t) return t;
65
+ var e = t[Symbol.toPrimitive];
66
+ if (void 0 !== e) {
67
+ var i = e.call(t, r || "default");
68
+ if ("object" != typeof i) return i;
88
69
  throw new TypeError("@@toPrimitive must return a primitive value.");
89
70
  }
90
- return (hint === "string" ? String : Number)(input);
71
+ return ("string" === r ? String : Number)(t);
91
72
  }
92
- function _toPropertyKey(arg) {
93
- var key = _toPrimitive(arg, "string");
94
- return typeof key === "symbol" ? key : String(key);
73
+ function _toPropertyKey(t) {
74
+ var i = _toPrimitive(t, "string");
75
+ return "symbol" == typeof i ? i : i + "";
95
76
  }
96
77
 
97
78
  var canvasToBlob = {exports: {}};
@@ -404,6 +385,49 @@ function getStringFromCharCode(dataView, start, length) {
404
385
  }
405
386
  return str;
406
387
  }
388
+
389
+ /**
390
+ * Check if `canvas.getContext('2d').getImageData` is available,
391
+ * FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode (#137)
392
+ * @link https://github.com/nodeca/pica/blob/master/lib/utils.js
393
+ * @returns {boolean} Returns `true` if it is available, else `false`.
394
+ */
395
+ function isCanvasAvailable() {
396
+ try {
397
+ var canvas = document.createElement('canvas');
398
+ canvas.width = 2;
399
+ canvas.height = 1;
400
+ var context = canvas.getContext('2d');
401
+ if (!context) return false;
402
+
403
+ // Create 2x1 image data containing RGBA values for two pixels
404
+ var imageData = context.createImageData(2, 1);
405
+
406
+ // First pixel: R=12, G=23, B=34, A=255
407
+ imageData.data[0] = 12;
408
+ imageData.data[1] = 23;
409
+ imageData.data[2] = 34;
410
+ imageData.data[3] = 255;
411
+
412
+ // Second pixel: R=45, G=56, B=67, A=255
413
+ imageData.data[4] = 45;
414
+ imageData.data[5] = 56;
415
+ imageData.data[6] = 67;
416
+ imageData.data[7] = 255;
417
+ context.putImageData(imageData, 0, 0);
418
+ var readBack = context.getImageData(0, 0, 2, 1);
419
+
420
+ // Expected pixel data (matching the written values)
421
+ var expected = [12, 23, 34, 255, 45, 56, 67, 255];
422
+
423
+ // Compare element by element to ensure write and read consistency
424
+ return readBack.data.every(function (value, index) {
425
+ return value === expected[index];
426
+ });
427
+ } catch (error) {
428
+ return false;
429
+ }
430
+ }
407
431
  var btoa = WINDOW.btoa;
408
432
 
409
433
  /**
@@ -671,7 +695,7 @@ var Compressor = /*#__PURE__*/function () {
671
695
  this.result = null;
672
696
  this.init();
673
697
  }
674
- _createClass(Compressor, [{
698
+ return _createClass(Compressor, [{
675
699
  key: "init",
676
700
  value: function init() {
677
701
  var _this = this;
@@ -757,10 +781,18 @@ var Compressor = /*#__PURE__*/function () {
757
781
  var file = this.file,
758
782
  image = this.image;
759
783
  image.onload = function () {
760
- _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
761
- naturalWidth: image.naturalWidth,
762
- naturalHeight: image.naturalHeight
763
- }));
784
+ if (isCanvasAvailable()) {
785
+ _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
786
+ naturalWidth: image.naturalWidth,
787
+ naturalHeight: image.naturalHeight
788
+ }));
789
+ } else {
790
+ _this2.done({
791
+ naturalWidth: image.naturalWidth,
792
+ naturalHeight: image.naturalHeight,
793
+ result: null
794
+ });
795
+ }
764
796
  };
765
797
  image.onabort = function () {
766
798
  _this2.fail(new Error('Aborted to load the image.'));
@@ -983,14 +1015,25 @@ var Compressor = /*#__PURE__*/function () {
983
1015
  if (options.strict && !options.retainExif && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
984
1016
  result = file;
985
1017
  } else {
986
- var date = new Date();
987
- result.lastModified = date.getTime();
988
- result.lastModifiedDate = date;
989
- result.name = file.name;
1018
+ var fileName = file.name;
990
1019
 
991
1020
  // Convert the extension to match its type
992
- if (result.name && result.type !== file.type) {
993
- result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1021
+ if (fileName && result.type !== file.type) {
1022
+ fileName = fileName.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1023
+ }
1024
+ try {
1025
+ // Convert the resulting Blob object into a File object for modern browsers.
1026
+ result = new File([result], fileName, {
1027
+ type: result.type
1028
+ });
1029
+ } catch (error) {
1030
+ // Fallback to Blob if the File constructor is not supported.
1031
+ var date = new Date();
1032
+ result.name = fileName;
1033
+
1034
+ // The last modified date is not accurate, but it's better than nothing.
1035
+ result.lastModified = date.getTime();
1036
+ result.lastModifiedDate = date;
994
1037
  }
995
1038
  }
996
1039
  } else {
@@ -1049,7 +1092,6 @@ var Compressor = /*#__PURE__*/function () {
1049
1092
  _extends(DEFAULTS, options);
1050
1093
  }
1051
1094
  }]);
1052
- return Compressor;
1053
1095
  }();
1054
1096
 
1055
1097
  export { Compressor as default };
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * Compressor.js v1.2.1
2
+ * Compressor.js v1.3.0
3
3
  * https://fengyuanchen.github.io/compressorjs
4
4
  *
5
5
  * Copyright 2018-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2023-02-28T14:09:41.732Z
8
+ * Date: 2026-04-06T07:12:45.816Z
9
9
  */
10
10
 
11
11
  (function (global, factory) {
@@ -14,90 +14,71 @@
14
14
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Compressor = factory());
15
15
  })(this, (function () { 'use strict';
16
16
 
17
- function ownKeys(object, enumerableOnly) {
18
- var keys = Object.keys(object);
19
- if (Object.getOwnPropertySymbols) {
20
- var symbols = Object.getOwnPropertySymbols(object);
21
- enumerableOnly && (symbols = symbols.filter(function (sym) {
22
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
23
- })), keys.push.apply(keys, symbols);
24
- }
25
- return keys;
17
+ function _classCallCheck(a, n) {
18
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
26
19
  }
27
- function _objectSpread2(target) {
28
- for (var i = 1; i < arguments.length; i++) {
29
- var source = null != arguments[i] ? arguments[i] : {};
30
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
31
- _defineProperty(target, key, source[key]);
32
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
33
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
34
- });
20
+ function _defineProperties(e, r) {
21
+ for (var t = 0; t < r.length; t++) {
22
+ var o = r[t];
23
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
35
24
  }
36
- return target;
37
25
  }
38
- function _classCallCheck(instance, Constructor) {
39
- if (!(instance instanceof Constructor)) {
40
- throw new TypeError("Cannot call a class as a function");
41
- }
26
+ function _createClass(e, r, t) {
27
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
28
+ writable: !1
29
+ }), e;
42
30
  }
43
- function _defineProperties(target, props) {
44
- for (var i = 0; i < props.length; i++) {
45
- var descriptor = props[i];
46
- descriptor.enumerable = descriptor.enumerable || false;
47
- descriptor.configurable = true;
48
- if ("value" in descriptor) descriptor.writable = true;
49
- Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
50
- }
31
+ function _defineProperty(e, r, t) {
32
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
33
+ value: t,
34
+ enumerable: !0,
35
+ configurable: !0,
36
+ writable: !0
37
+ }) : e[r] = t, e;
51
38
  }
52
- function _createClass(Constructor, protoProps, staticProps) {
53
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
54
- if (staticProps) _defineProperties(Constructor, staticProps);
55
- Object.defineProperty(Constructor, "prototype", {
56
- writable: false
57
- });
58
- return Constructor;
39
+ function _extends() {
40
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
41
+ for (var e = 1; e < arguments.length; e++) {
42
+ var t = arguments[e];
43
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
44
+ }
45
+ return n;
46
+ }, _extends.apply(null, arguments);
59
47
  }
60
- function _defineProperty(obj, key, value) {
61
- key = _toPropertyKey(key);
62
- if (key in obj) {
63
- Object.defineProperty(obj, key, {
64
- value: value,
65
- enumerable: true,
66
- configurable: true,
67
- writable: true
68
- });
69
- } else {
70
- obj[key] = value;
48
+ function ownKeys(e, r) {
49
+ var t = Object.keys(e);
50
+ if (Object.getOwnPropertySymbols) {
51
+ var o = Object.getOwnPropertySymbols(e);
52
+ r && (o = o.filter(function (r) {
53
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
54
+ })), t.push.apply(t, o);
71
55
  }
72
- return obj;
56
+ return t;
73
57
  }
74
- function _extends() {
75
- _extends = Object.assign ? Object.assign.bind() : function (target) {
76
- for (var i = 1; i < arguments.length; i++) {
77
- var source = arguments[i];
78
- for (var key in source) {
79
- if (Object.prototype.hasOwnProperty.call(source, key)) {
80
- target[key] = source[key];
81
- }
82
- }
83
- }
84
- return target;
85
- };
86
- return _extends.apply(this, arguments);
58
+ function _objectSpread2(e) {
59
+ for (var r = 1; r < arguments.length; r++) {
60
+ var t = null != arguments[r] ? arguments[r] : {};
61
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
62
+ _defineProperty(e, r, t[r]);
63
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
64
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
65
+ });
66
+ }
67
+ return e;
87
68
  }
88
- function _toPrimitive(input, hint) {
89
- if (typeof input !== "object" || input === null) return input;
90
- var prim = input[Symbol.toPrimitive];
91
- if (prim !== undefined) {
92
- var res = prim.call(input, hint || "default");
93
- if (typeof res !== "object") return res;
69
+ function _toPrimitive(t, r) {
70
+ if ("object" != typeof t || !t) return t;
71
+ var e = t[Symbol.toPrimitive];
72
+ if (void 0 !== e) {
73
+ var i = e.call(t, r || "default");
74
+ if ("object" != typeof i) return i;
94
75
  throw new TypeError("@@toPrimitive must return a primitive value.");
95
76
  }
96
- return (hint === "string" ? String : Number)(input);
77
+ return ("string" === r ? String : Number)(t);
97
78
  }
98
- function _toPropertyKey(arg) {
99
- var key = _toPrimitive(arg, "string");
100
- return typeof key === "symbol" ? key : String(key);
79
+ function _toPropertyKey(t) {
80
+ var i = _toPrimitive(t, "string");
81
+ return "symbol" == typeof i ? i : i + "";
101
82
  }
102
83
 
103
84
  var canvasToBlob = {exports: {}};
@@ -410,6 +391,49 @@
410
391
  }
411
392
  return str;
412
393
  }
394
+
395
+ /**
396
+ * Check if `canvas.getContext('2d').getImageData` is available,
397
+ * FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode (#137)
398
+ * @link https://github.com/nodeca/pica/blob/master/lib/utils.js
399
+ * @returns {boolean} Returns `true` if it is available, else `false`.
400
+ */
401
+ function isCanvasAvailable() {
402
+ try {
403
+ var canvas = document.createElement('canvas');
404
+ canvas.width = 2;
405
+ canvas.height = 1;
406
+ var context = canvas.getContext('2d');
407
+ if (!context) return false;
408
+
409
+ // Create 2x1 image data containing RGBA values for two pixels
410
+ var imageData = context.createImageData(2, 1);
411
+
412
+ // First pixel: R=12, G=23, B=34, A=255
413
+ imageData.data[0] = 12;
414
+ imageData.data[1] = 23;
415
+ imageData.data[2] = 34;
416
+ imageData.data[3] = 255;
417
+
418
+ // Second pixel: R=45, G=56, B=67, A=255
419
+ imageData.data[4] = 45;
420
+ imageData.data[5] = 56;
421
+ imageData.data[6] = 67;
422
+ imageData.data[7] = 255;
423
+ context.putImageData(imageData, 0, 0);
424
+ var readBack = context.getImageData(0, 0, 2, 1);
425
+
426
+ // Expected pixel data (matching the written values)
427
+ var expected = [12, 23, 34, 255, 45, 56, 67, 255];
428
+
429
+ // Compare element by element to ensure write and read consistency
430
+ return readBack.data.every(function (value, index) {
431
+ return value === expected[index];
432
+ });
433
+ } catch (error) {
434
+ return false;
435
+ }
436
+ }
413
437
  var btoa = WINDOW.btoa;
414
438
 
415
439
  /**
@@ -677,7 +701,7 @@
677
701
  this.result = null;
678
702
  this.init();
679
703
  }
680
- _createClass(Compressor, [{
704
+ return _createClass(Compressor, [{
681
705
  key: "init",
682
706
  value: function init() {
683
707
  var _this = this;
@@ -763,10 +787,18 @@
763
787
  var file = this.file,
764
788
  image = this.image;
765
789
  image.onload = function () {
766
- _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
767
- naturalWidth: image.naturalWidth,
768
- naturalHeight: image.naturalHeight
769
- }));
790
+ if (isCanvasAvailable()) {
791
+ _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
792
+ naturalWidth: image.naturalWidth,
793
+ naturalHeight: image.naturalHeight
794
+ }));
795
+ } else {
796
+ _this2.done({
797
+ naturalWidth: image.naturalWidth,
798
+ naturalHeight: image.naturalHeight,
799
+ result: null
800
+ });
801
+ }
770
802
  };
771
803
  image.onabort = function () {
772
804
  _this2.fail(new Error('Aborted to load the image.'));
@@ -989,14 +1021,25 @@
989
1021
  if (options.strict && !options.retainExif && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
990
1022
  result = file;
991
1023
  } else {
992
- var date = new Date();
993
- result.lastModified = date.getTime();
994
- result.lastModifiedDate = date;
995
- result.name = file.name;
1024
+ var fileName = file.name;
996
1025
 
997
1026
  // Convert the extension to match its type
998
- if (result.name && result.type !== file.type) {
999
- result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1027
+ if (fileName && result.type !== file.type) {
1028
+ fileName = fileName.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1029
+ }
1030
+ try {
1031
+ // Convert the resulting Blob object into a File object for modern browsers.
1032
+ result = new File([result], fileName, {
1033
+ type: result.type
1034
+ });
1035
+ } catch (error) {
1036
+ // Fallback to Blob if the File constructor is not supported.
1037
+ var date = new Date();
1038
+ result.name = fileName;
1039
+
1040
+ // The last modified date is not accurate, but it's better than nothing.
1041
+ result.lastModified = date.getTime();
1042
+ result.lastModifiedDate = date;
1000
1043
  }
1001
1044
  }
1002
1045
  } else {
@@ -1055,7 +1098,6 @@
1055
1098
  _extends(DEFAULTS, options);
1056
1099
  }
1057
1100
  }]);
1058
- return Compressor;
1059
1101
  }();
1060
1102
 
1061
1103
  return Compressor;
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * Compressor.js v1.2.1
2
+ * Compressor.js v1.3.0
3
3
  * https://fengyuanchen.github.io/compressorjs
4
4
  *
5
5
  * Copyright 2018-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2023-02-28T14:09:41.732Z
8
+ * Date: 2026-04-06T07:12:45.816Z
9
9
  */
10
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()}(this,function(){"use strict";function t(t,e){var r,i=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),i.push.apply(i,r)),i}function n(i){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?t(Object(n),!0).forEach(function(e){var t,r;t=i,r=n[e=e],(e=o(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r}):Object.getOwnPropertyDescriptors?Object.defineProperties(i,Object.getOwnPropertyDescriptors(n)):t(Object(n)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(n,e))})}return i}function a(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,o(i.key),i)}}function s(){return(s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r,i=arguments[t];for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r])}return e}).apply(this,arguments)}function o(e){e=function(e,t){if("object"!=typeof e||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0===r)return("string"===t?String:Number)(e);if("object"!=typeof(r=r.call(e,t||"default")))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}(e,"string");return"symbol"==typeof e?e:String(e)}function O(e){return 0<e&&e<1/0}var e,r,l,c,h,u,f,d,i={exports:{}},j=(e=i,"undefined"!=typeof window&&(l=(r=window).HTMLCanvasElement&&r.HTMLCanvasElement.prototype,c=r.Blob&&function(){try{return Boolean(new Blob)}catch(e){return!1}}(),h=c&&r.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(e){return!1}}(),u=r.BlobBuilder||r.WebKitBlobBuilder||r.MozBlobBuilder||r.MSBlobBuilder,f=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,d=(c||u)&&r.atob&&r.ArrayBuffer&&r.Uint8Array&&function(e){var t,r,i,n,a,o=e.match(f);if(!o)throw new Error("invalid data URI");for(t=o[2]?o[1]:"text/plain"+(o[3]||";charset=US-ASCII"),a=!!o[4],e=e.slice(o[0].length),r=(a?atob:decodeURIComponent)(e),o=new ArrayBuffer(r.length),i=new Uint8Array(o),n=0;n<r.length;n+=1)i[n]=r.charCodeAt(n);return c?new Blob([h?i:o],{type:t}):((a=new u).append(o),a.getBlob(t))},r.HTMLCanvasElement&&!l.toBlob&&(l.mozGetAsFile?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){r&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.mozGetAsFile("blob",t))})}:l.toDataURL&&d&&(l.msToBlob?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){(t&&"image/png"!==t||r)&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.msToBlob(t))})}:l.toBlob=function(e,t,r){var i=this;setTimeout(function(){e(d(i.toDataURL(t,r)))})})),e.exports?e.exports=d:r.dataURLtoBlob=d),i.exports),m={strict:!0,checkOrientation:!0,retainExif:!1,maxWidth:1/0,maxHeight:1/0,minWidth:0,minHeight:0,width:void 0,height:void 0,resize:"none",quality:.8,mimeType:"auto",convertTypes:["image/png"],convertSize:5e6,beforeDraw:null,drew:null,success:null,error:null},b="undefined"!=typeof window&&void 0!==window.document?window:{},p=Array.prototype.slice;function x(e){return Array.from?Array.from(e):p.call(e)}var g=/^image\/.+$/;function T(e){return g.test(e)}var y=String.fromCharCode;var w=b.btoa;function A(e,t){for(var r=[],i=new Uint8Array(e);0<i.length;)r.push(y.apply(null,x(i.subarray(0,8192)))),i=i.subarray(8192);return"data:".concat(t,";base64,").concat(w(r.join("")))}function v(e){var t,r,i,n,a,o,l,s=new DataView(e);try{if(255===s.getUint8(0)&&216===s.getUint8(1))for(var c=s.byteLength,h=2;h+1<c;){if(255===s.getUint8(h)&&225===s.getUint8(h+1)){r=h;break}h+=1}if(i=r&&(n=r+10,"Exif"===function(e,t,r){var i,n="";for(r+=t,i=t;i<r;i+=1)n+=y(e.getUint8(i));return n}(s,r+4,4))&&((l=18761===(a=s.getUint16(n)))||19789===a)&&42===s.getUint16(n+2,l)&&8<=(o=s.getUint32(n+4,l))?n+o:i)for(var u,f=s.getUint16(i,l),d=0;d<f;d+=1)if(u=i+12*d+2,274===s.getUint16(u,l)){u+=8,t=s.getUint16(u,l),s.setUint16(u,1,l);break}}catch(e){t=1}return t}var B=/\.\d*(?:0|9){12}\d*$/;function R(e,t){t=1<arguments.length&&void 0!==t?t:1e11;return B.test(e)?Math.round(e*t)/t:e}function E(e,t){var r,i=e.aspectRatio,n=e.height,e=e.width,t=1<arguments.length&&void 0!==t?t:"none",a=O(e),o=O(n);return a&&o?(r=n*i,("contain"===t||"none"===t)&&e<r||"cover"===t&&r<e?n=e/i:e=n*i):a?n=e/i:o&&(e=n*i),{width:e,height:n}}var U=b.ArrayBuffer,k=b.FileReader,M=b.URL||b.webkitURL,D=/\.\w+$/,L=b.Compressor;return function(){function r(e,t){if(!(this instanceof r))throw new TypeError("Cannot call a class as a function");this.file=e,this.exif=[],this.image=new Image,this.options=n(n({},m),t),this.aborted=!1,this.result=null,this.init()}var e,t,i;return e=r,i=[{key:"noConflict",value:function(){return window.Compressor=L,r}},{key:"setDefaults",value:function(e){s(m,e)}}],(t=[{key:"init",value:function(){var i,n,a,e,o=this,l=this.file,t=this.options;e=l,"undefined"!=typeof Blob&&(e instanceof Blob||"[object Blob]"===Object.prototype.toString.call(e))?T(i=l.type)?M&&k?(U||(t.checkOrientation=!1,t.retainExif=!1),n=(e="image/jpeg"===i)&&t.checkOrientation,a=e&&t.retainExif,!M||n||a?(e=new k,(this.reader=e).onload=function(e){var e=e.target.result,t={},r=1;n&&1<(r=v(e))&&s(t,function(e){var t=0,r=1,i=1;switch(e){case 2:r=-1;break;case 3:t=-180;break;case 4:i=-1;break;case 5:t=90,i=-1;break;case 6:t=90;break;case 7:t=90,r=-1;break;case 8:t=-90}return{rotate:t,scaleX:r,scaleY:i}}(r)),a&&(o.exif=function(e){for(var t=x(new Uint8Array(e)),r=t.length,i=[],n=0;n+3<r;){var a=t[n],o=t[n+1];if(255===a&&218===o)break;255===a&&216===o?n+=2:(a=n+(256*t[n+2]+t[n+3])+2,o=t.slice(n,a),i.push(o),n=a)}return i.reduce(function(e,t){return 255===t[0]&&225===t[1]?e.concat(t):e},[])}(e)),t.url=n||a?!M||1<r?A(e,i):M.createObjectURL(l):e,o.load(t)},e.onabort=function(){o.fail(new Error("Aborted to read the image with FileReader."))},e.onerror=function(){o.fail(new Error("Failed to read the image with FileReader."))},e.onloadend=function(){o.reader=null},n||a?e.readAsArrayBuffer(l):e.readAsDataURL(l)):this.load({url:M.createObjectURL(l)})):this.fail(new Error("The current browser does not support image compression.")):this.fail(new Error("The first argument must be an image File or Blob object.")):this.fail(new Error("The first argument must be a File or Blob object."))}},{key:"load",value:function(e){var t=this,r=this.file,i=this.image;i.onload=function(){t.draw(n(n({},e),{},{naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight}))},i.onabort=function(){t.fail(new Error("Aborted to load the image."))},i.onerror=function(){t.fail(new Error("Failed to load the image."))},b.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(b.navigator.userAgent)&&(i.crossOrigin="anonymous"),i.alt=r.name,i.src=e.url}},{key:"draw",value:function(e){var n=this,a=e.naturalWidth,o=e.naturalHeight,t=e.rotate,t=void 0===t?0:t,r=e.scaleX,r=void 0===r?1:r,e=e.scaleY,e=void 0===e?1:e,i=this.file,l=this.image,s=this.options,c=document.createElement("canvas"),h=c.getContext("2d"),u=Math.abs(t)%180==90,f=("contain"===s.resize||"cover"===s.resize)&&O(s.width)&&O(s.height),d=Math.max(s.maxWidth,0)||1/0,m=Math.max(s.maxHeight,0)||1/0,b=Math.max(s.minWidth,0)||0,p=Math.max(s.minHeight,0)||0,g=a/o,y=s.width,w=s.height,v=(u&&(d=(v=[m,d])[0],m=v[1],b=(v=[p,b])[0],p=v[1],y=(v=[w,y])[0],w=v[1]),E({aspectRatio:g=f?y/w:g,width:d,height:m},"contain")),v=(d=v.width,m=v.height,E({aspectRatio:g,width:b,height:p},"cover")),v=(b=v.width,p=v.height,w=f?(y=(v=E({aspectRatio:g,width:y,height:w},s.resize)).width,v.height):(y=void 0===(B=(v=E({aspectRatio:g,width:y,height:w})).width)?a:B,void 0===(B=v.height)?o:B),-(y=Math.floor(R(Math.min(Math.max(y,b),d))))/2),B=-(w=Math.floor(R(Math.min(Math.max(w,p),m))))/2,b=y,d=w,p=[],m=(f&&(0,m=(g=E({aspectRatio:g,width:m=a,height:f=o},{contain:"cover",cover:"contain"}[s.resize])).width,f=g.height,p.push((a-m)/2,(o-f)/2,m,f)),p.push(v,B,b,d),u&&(y=(g=[w,y])[0],w=g[1]),c.width=y,c.height=w,T(s.mimeType)||(s.mimeType=i.type),"transparent"),U=(i.size>s.convertSize&&0<=s.convertTypes.indexOf(s.mimeType)&&(s.mimeType="image/jpeg"),"image/jpeg"===s.mimeType);h.fillStyle=m=U?"#fff":m,h.fillRect(0,0,y,w),s.beforeDraw&&s.beforeDraw.call(this,h,c),this.aborted||(h.save(),h.translate(y/2,w/2),h.rotate(t*Math.PI/180),h.scale(r,e),h.drawImage.apply(h,[l].concat(p)),h.restore(),s.drew&&s.drew.call(this,h,c),this.aborted)||(f=function(e){var i,t,r;n.aborted||(i=function(e){return n.done({naturalWidth:a,naturalHeight:o,result:e})},e&&U&&s.retainExif&&n.exif&&0<n.exif.length?(t=function(e){return i(j(A((e=e,t=n.exif,255!==(r=x(new Uint8Array(e)))[2]||224!==r[3]?e:(e=256*r[4]+r[5],t=[255,216].concat(t,r.slice(4+e)),new Uint8Array(t))),s.mimeType)));var t,r},e.arrayBuffer?e.arrayBuffer().then(t).catch(function(){n.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))}):(r=new k,(n.reader=r).onload=function(e){e=e.target;t(e.result)},r.onabort=function(){n.fail(new Error("Aborted to read the compressed image with FileReader."))},r.onerror=function(){n.fail(new Error("Failed to read the compressed image with FileReader."))},r.onloadend=function(){n.reader=null},r.readAsArrayBuffer(e))):i(e))},c.toBlob?c.toBlob(f,s.mimeType,s.quality):f(j(c.toDataURL(s.mimeType,s.quality))))}},{key:"done",value:function(e){var t=e.naturalWidth,r=e.naturalHeight,e=e.result,i=this.file,n=this.image,a=this.options;M&&0===n.src.indexOf("blob:")&&M.revokeObjectURL(n.src),!e||a.strict&&!a.retainExif&&e.size>i.size&&a.mimeType===i.type&&!(a.width>t||a.height>r||a.minWidth>t||a.minHeight>r||a.maxWidth<t||a.maxHeight<r)?e=i:(n=new Date,e.lastModified=n.getTime(),e.lastModifiedDate=n,e.name=i.name,e.name&&e.type!==i.type&&(e.name=e.name.replace(D,(t=T(t=e.type)?t.substr(6):"",".".concat(t="jpeg"===t?"jpg":t))))),this.result=e,a.success&&a.success.call(this,e)}},{key:"fail",value:function(e){var t=this.options;if(!t.error)throw e;t.error.call(this,e)}},{key:"abort",value:function(){this.aborted||(this.aborted=!0,this.reader?this.reader.abort():this.image.complete?this.fail(new Error("The compression process has been aborted.")):(this.image.onload=null,this.image.onabort()))}}])&&a(e.prototype,t),i&&a(e,i),Object.defineProperty(e,"prototype",{writable:!1}),r}()});
10
+ ((e,t)=>{"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()})(this,function(){function a(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,o(i.key),i)}}function s(){return(s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r,i=arguments[t];for(r in i)!{}.hasOwnProperty.call(i,r)||(e[r]=i[r])}return e}).apply(null,arguments)}function t(t,e){var r,i=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),i.push.apply(i,r)),i}function n(i){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?t(Object(a),!0).forEach(function(e){var t,r;t=i,r=a[e=e],(e=o(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r}):Object.getOwnPropertyDescriptors?Object.defineProperties(i,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(a,e))})}return i}function o(e){e=((e,t)=>{if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0===r)return("string"===t?String:Number)(e);if("object"!=typeof(r=r.call(e,t||"default")))return r;throw new TypeError("@@toPrimitive must return a primitive value.")})(e,"string");return"symbol"==typeof e?e:e+""}function x(e){return 0<e&&e<1/0}var e,r,l,c,h,u,f,d,i={exports:{}},O=(e=i,"undefined"!=typeof window&&(l=(r=window).HTMLCanvasElement&&r.HTMLCanvasElement.prototype,c=r.Blob&&(()=>{try{return Boolean(new Blob)}catch(e){return!1}})(),h=c&&r.Uint8Array&&(()=>{try{return 100===new Blob([new Uint8Array(100)]).size}catch(e){return!1}})(),u=r.BlobBuilder||r.WebKitBlobBuilder||r.MozBlobBuilder||r.MSBlobBuilder,f=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,d=(c||u)&&r.atob&&r.ArrayBuffer&&r.Uint8Array&&function(e){var t,r,i,a,n,o=e.match(f);if(!o)throw new Error("invalid data URI");for(t=o[2]?o[1]:"text/plain"+(o[3]||";charset=US-ASCII"),n=!!o[4],e=e.slice(o[0].length),r=(n?atob:decodeURIComponent)(e),o=new ArrayBuffer(r.length),i=new Uint8Array(o),a=0;a<r.length;a+=1)i[a]=r.charCodeAt(a);return c?new Blob([h?i:o],{type:t}):((n=new u).append(o),n.getBlob(t))},r.HTMLCanvasElement&&!l.toBlob&&(l.mozGetAsFile?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){r&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.mozGetAsFile("blob",t))})}:l.toDataURL&&d&&(l.msToBlob?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){(t&&"image/png"!==t||r)&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.msToBlob(t))})}:l.toBlob=function(e,t,r){var i=this;setTimeout(function(){e(d(i.toDataURL(t,r)))})})),e.exports?e.exports=d:r.dataURLtoBlob=d),i.exports),m={strict:!0,checkOrientation:!0,retainExif:!1,maxWidth:1/0,maxHeight:1/0,minWidth:0,minHeight:0,width:void 0,height:void 0,resize:"none",quality:.8,mimeType:"auto",convertTypes:["image/png"],convertSize:5e6,beforeDraw:null,drew:null,success:null,error:null},g="undefined"!=typeof window&&void 0!==window.document?window:{},p=Array.prototype.slice;function j(e){return Array.from?Array.from(e):p.call(e)}var b=/^image\/.+$/;function T(e){return b.test(e)}var y=String.fromCharCode;var w=g.btoa;function A(e,t){for(var r=[],i=new Uint8Array(e);0<i.length;)r.push(y.apply(null,j(i.subarray(0,8192)))),i=i.subarray(8192);return"data:".concat(t,";base64,").concat(w(r.join("")))}function v(e){var t,r,i,a,n,o,l,s=new DataView(e);try{if(255===s.getUint8(0)&&216===s.getUint8(1))for(var c=s.byteLength,h=2;h+1<c;){if(255===s.getUint8(h)&&225===s.getUint8(h+1)){r=h;break}h+=1}if(i=r&&(a=r+10,"Exif"===((e,t,r)=>{var i,a="";for(r+=t,i=t;i<r;i+=1)a+=y(e.getUint8(i));return a})(s,r+4,4))&&((l=18761===(n=s.getUint16(a)))||19789===n)&&42===s.getUint16(a+2,l)&&8<=(o=s.getUint32(a+4,l))?a+o:i)for(var u,f=s.getUint16(i,l),d=0;d<f;d+=1)if(u=i+12*d+2,274===s.getUint16(u,l)){u+=8,t=s.getUint16(u,l),s.setUint16(u,1,l);break}}catch(e){t=1}return t}var B=/\.\d*(?:0|9){12}\d*$/;function R(e,t){t=1<arguments.length&&void 0!==t?t:1e11;return B.test(e)?Math.round(e*t)/t:e}function E(e,t){var r,i=e.aspectRatio,a=e.height,e=e.width,t=1<arguments.length&&void 0!==t?t:"none",n=x(e),o=x(a);return n&&o?(r=a*i,("contain"===t||"none"===t)&&e<r||"cover"===t&&r<e?a=e/i:e=a*i):n?a=e/i:o&&(e=a*i),{width:e,height:a}}var U=g.ArrayBuffer,k=g.FileReader,D=g.URL||g.webkitURL,M=/\.\w+$/,L=g.Compressor;return(()=>{function r(e,t){if(!(this instanceof r))throw new TypeError("Cannot call a class as a function");this.file=e,this.exif=[],this.image=new Image,this.options=n(n({},m),t),this.aborted=!1,this.result=null,this.init()}return e=r,i=[{key:"noConflict",value:function(){return window.Compressor=L,r}},{key:"setDefaults",value:function(e){s(m,e)}}],(t=[{key:"init",value:function(){var i,a,n,e,o=this,l=this.file,t=this.options;e=l,"undefined"!=typeof Blob&&(e instanceof Blob||"[object Blob]"===Object.prototype.toString.call(e))?T(i=l.type)?D&&k?(U||(t.checkOrientation=!1,t.retainExif=!1),a=(e="image/jpeg"===i)&&t.checkOrientation,n=e&&t.retainExif,!D||a||n?(e=new k,(this.reader=e).onload=function(e){var e=e.target.result,t={},r=1;a&&1<(r=v(e))&&s(t,(e=>{var t=0,r=1,i=1;switch(e){case 2:r=-1;break;case 3:t=-180;break;case 4:i=-1;break;case 5:t=90,i=-1;break;case 6:t=90;break;case 7:t=90,r=-1;break;case 8:t=-90}return{rotate:t,scaleX:r,scaleY:i}})(r)),n&&(o.exif=(e=>{for(var t=j(new Uint8Array(e)),r=t.length,i=[],a=0;a+3<r;){var n=t[a],o=t[a+1];if(255===n&&218===o)break;255===n&&216===o?a+=2:(n=a+(256*t[a+2]+t[a+3])+2,o=t.slice(a,n),i.push(o),a=n)}return i.reduce(function(e,t){return 255===t[0]&&225===t[1]?e.concat(t):e},[])})(e)),t.url=a||n?!D||1<r?A(e,i):D.createObjectURL(l):e,o.load(t)},e.onabort=function(){o.fail(new Error("Aborted to read the image with FileReader."))},e.onerror=function(){o.fail(new Error("Failed to read the image with FileReader."))},e.onloadend=function(){o.reader=null},a||n?e.readAsArrayBuffer(l):e.readAsDataURL(l)):this.load({url:D.createObjectURL(l)})):this.fail(new Error("The current browser does not support image compression.")):this.fail(new Error("The first argument must be an image File or Blob object.")):this.fail(new Error("The first argument must be a File or Blob object."))}},{key:"load",value:function(e){var t=this,r=this.file,i=this.image;i.onload=function(){(()=>{try{var e,t,r,i=document.createElement("canvas"),a=(i.width=2,i.height=1,i.getContext("2d"));if(a)return(e=a.createImageData(2,1)).data[0]=12,e.data[1]=23,e.data[2]=34,e.data[3]=255,e.data[4]=45,e.data[5]=56,e.data[6]=67,e.data[7]=255,a.putImageData(e,0,0),t=a.getImageData(0,0,2,1),r=[12,23,34,255,45,56,67,255],t.data.every(function(e,t){return e===r[t]})}catch(e){}})()?t.draw(n(n({},e),{},{naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight})):t.done({naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight,result:null})},i.onabort=function(){t.fail(new Error("Aborted to load the image."))},i.onerror=function(){t.fail(new Error("Failed to load the image."))},g.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(g.navigator.userAgent)&&(i.crossOrigin="anonymous"),i.alt=r.name,i.src=e.url}},{key:"draw",value:function(e){var a=this,n=e.naturalWidth,o=e.naturalHeight,t=e.rotate,t=void 0===t?0:t,r=e.scaleX,r=void 0===r?1:r,e=e.scaleY,e=void 0===e?1:e,i=this.file,l=this.image,s=this.options,c=document.createElement("canvas"),h=c.getContext("2d"),u=Math.abs(t)%180==90,f=("contain"===s.resize||"cover"===s.resize)&&x(s.width)&&x(s.height),d=Math.max(s.maxWidth,0)||1/0,m=Math.max(s.maxHeight,0)||1/0,g=Math.max(s.minWidth,0)||0,p=Math.max(s.minHeight,0)||0,b=n/o,y=s.width,w=s.height,v=(u&&(d=(v=[m,d])[0],m=v[1],g=(v=[p,g])[0],p=v[1],y=(v=[w,y])[0],w=v[1]),E({aspectRatio:b=f?y/w:b,width:d,height:m},"contain")),v=(d=v.width,m=v.height,E({aspectRatio:b,width:g,height:p},"cover")),v=(g=v.width,p=v.height,w=f?(y=(v=E({aspectRatio:b,width:y,height:w},s.resize)).width,v.height):(y=void 0===(B=(v=E({aspectRatio:b,width:y,height:w})).width)?n:B,void 0===(B=v.height)?o:B),-(y=Math.floor(R(Math.min(Math.max(y,g),d))))/2),B=-(w=Math.floor(R(Math.min(Math.max(w,p),m))))/2,g=y,d=w,p=[],m=(f&&(0,m=(b=E({aspectRatio:b,width:m=n,height:f=o},{contain:"cover",cover:"contain"}[s.resize])).width,p.push((n-m)/2,(o-(f=b.height))/2,m,f)),p.push(v,B,g,d),u&&(y=(b=[w,y])[0],w=b[1]),c.width=y,c.height=w,T(s.mimeType)||(s.mimeType=i.type),"transparent"),U=(i.size>s.convertSize&&0<=s.convertTypes.indexOf(s.mimeType)&&(s.mimeType="image/jpeg"),"image/jpeg"===s.mimeType);h.fillStyle=m=U?"#fff":m,h.fillRect(0,0,y,w),s.beforeDraw&&s.beforeDraw.call(this,h,c),this.aborted||(h.save(),h.translate(y/2,w/2),h.rotate(t*Math.PI/180),h.scale(r,e),h.drawImage.apply(h,[l].concat(p)),h.restore(),s.drew&&s.drew.call(this,h,c),this.aborted)||(f=function(e){var i,t,r;a.aborted||(i=function(e){return a.done({naturalWidth:n,naturalHeight:o,result:e})},e&&U&&s.retainExif&&a.exif&&0<a.exif.length?(t=function(e){return i(O(A((e=e,t=a.exif,255!==(r=j(new Uint8Array(e)))[2]||224!==r[3]?e:(e=[255,216].concat(t,r.slice(4+(256*r[4]+r[5]))),new Uint8Array(e))),s.mimeType)));var t,r},e.arrayBuffer?e.arrayBuffer().then(t).catch(function(){a.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))}):(r=new k,(a.reader=r).onload=function(e){e=e.target;t(e.result)},r.onabort=function(){a.fail(new Error("Aborted to read the compressed image with FileReader."))},r.onerror=function(){a.fail(new Error("Failed to read the compressed image with FileReader."))},r.onloadend=function(){a.reader=null},r.readAsArrayBuffer(e))):i(e))},c.toBlob?c.toBlob(f,s.mimeType,s.quality):f(O(c.toDataURL(s.mimeType,s.quality))))}},{key:"done",value:function(t){var e=t.naturalWidth,r=t.naturalHeight,t=t.result,i=this.file,a=this.image,n=this.options;if(D&&0===a.src.indexOf("blob:")&&D.revokeObjectURL(a.src),t)if(n.strict&&!n.retainExif&&t.size>i.size&&n.mimeType===i.type&&!(n.width>e||n.height>r||n.minWidth>e||n.minHeight>r||n.maxWidth<e||n.maxHeight<r))t=i;else{a=i.name;a&&t.type!==i.type&&(a=a.replace(M,(e=T(e=t.type)?e.substr(6):"",".".concat(e="jpeg"===e?"jpg":e))));try{t=new File([t],a,{type:t.type})}catch(e){r=new Date;t.name=a,t.lastModified=r.getTime(),t.lastModifiedDate=r}}else t=i;this.result=t,n.success&&n.success.call(this,t)}},{key:"fail",value:function(e){var t=this.options;if(!t.error)throw e;t.error.call(this,e)}},{key:"abort",value:function(){this.aborted||(this.aborted=!0,this.reader?this.reader.abort():this.image.complete?this.fail(new Error("The compression process has been aborted.")):(this.image.onload=null,this.image.onabort()))}}])&&a(e.prototype,t),i&&a(e,i),Object.defineProperty(e,"prototype",{writable:!1}),e;var e,t,i})()});
package/package.json CHANGED
@@ -1,34 +1,16 @@
1
1
  {
2
2
  "name": "compressorjs",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "JavaScript image compressor.",
5
5
  "main": "dist/compressor.common.js",
6
6
  "module": "dist/compressor.esm.js",
7
7
  "browser": "dist/compressor.js",
8
8
  "types": "types/index.d.ts",
9
- "repository": "fengyuanchen/compressorjs",
10
- "homepage": "https://fengyuanchen.github.io/compressorjs",
11
- "license": "MIT",
12
- "author": {
13
- "name": "Chen Fengyuan",
14
- "url": "https://chenfengyuan.com/"
15
- },
16
9
  "files": [
17
10
  "src",
18
11
  "dist",
19
12
  "types"
20
13
  ],
21
- "keywords": [
22
- "image",
23
- "compress",
24
- "compressor",
25
- "compressor.js",
26
- "image-compressor",
27
- "lossy-compression",
28
- "javascript",
29
- "front-end",
30
- "web"
31
- ],
32
14
  "scripts": {
33
15
  "build": "rollup -c",
34
16
  "clean": "del-cli dist",
@@ -40,48 +22,71 @@
40
22
  "prepare": "husky install",
41
23
  "release": "npm run clean && npm run lint && npm run build && npm run compress && npm test",
42
24
  "start": "npm run dev",
43
- "test": "cross-env NODE_ENV=test karma start test/karma.conf.js",
44
- "test:coverage": "cat coverage/lcov.info | codecov"
25
+ "test": "cross-env NODE_ENV=test karma start test/karma.conf.js"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/fengyuanchen/compressorjs.git"
45
30
  },
31
+ "keywords": [
32
+ "image",
33
+ "compress",
34
+ "compressor",
35
+ "compressor.js",
36
+ "image-compressor",
37
+ "lossy-compression",
38
+ "javascript",
39
+ "front-end",
40
+ "web"
41
+ ],
42
+ "author": {
43
+ "name": "Chen Fengyuan",
44
+ "url": "https://chenfengyuan.com/"
45
+ },
46
+ "license": "MIT",
47
+ "bugs": {
48
+ "url": "https://github.com/fengyuanchen/compressorjs/issues"
49
+ },
50
+ "homepage": "https://fengyuanchen.github.io/compressorjs",
46
51
  "dependencies": {
47
52
  "blueimp-canvas-to-blob": "^3.29.0",
48
53
  "is-blob": "^2.1.0"
49
54
  },
50
55
  "devDependencies": {
51
- "@babel/core": "^7.21.0",
52
- "@babel/plugin-transform-object-assign": "^7.18.6",
53
- "@babel/preset-env": "^7.20.2",
54
- "@commitlint/cli": "^17.4.4",
55
- "@commitlint/config-conventional": "^17.4.4",
56
+ "@babel/core": "^7.29.0",
57
+ "@babel/plugin-transform-object-assign": "^7.27.1",
58
+ "@babel/preset-env": "^7.29.2",
59
+ "@commitlint/cli": "^17.8.1",
60
+ "@commitlint/config-conventional": "^17.8.1",
56
61
  "@rollup/plugin-babel": "^5.3.1",
57
62
  "@rollup/plugin-commonjs": "^21.1.0",
58
63
  "@rollup/plugin-node-resolve": "^13.3.0",
59
64
  "@rollup/plugin-replace": "^3.1.0",
60
65
  "babel-plugin-istanbul": "^6.1.1",
61
- "chai": "^4.3.7",
66
+ "chai": "^4.5.0",
62
67
  "change-case": "^4.1.2",
63
68
  "codecov": "^3.8.3",
64
69
  "create-banner": "^2.0.0",
65
70
  "cross-env": "^7.0.3",
66
- "del-cli": "^5.0.0",
67
- "eslint": "^8.35.0",
71
+ "del-cli": "^5.1.0",
72
+ "eslint": "^8.57.1",
68
73
  "eslint-config-airbnb-base": "^15.0.0",
69
- "eslint-plugin-import": "^2.27.5",
74
+ "eslint-plugin-import": "^2.32.0",
70
75
  "husky": "^8.0.3",
71
- "karma": "^6.4.1",
76
+ "karma": "^6.4.4",
72
77
  "karma-chai": "^0.1.0",
73
- "karma-chrome-launcher": "^3.1.1",
78
+ "karma-chrome-launcher": "^3.2.0",
74
79
  "karma-coverage-istanbul-reporter": "^3.0.3",
75
80
  "karma-mocha": "^2.0.1",
76
81
  "karma-mocha-reporter": "^2.2.5",
77
82
  "karma-rollup-preprocessor": "^7.0.8",
78
- "lint-staged": "^13.1.2",
79
- "mocha": "^10.2.0",
80
- "puppeteer": "^19.7.2",
81
- "rollup": "^2.79.1",
82
- "stylelint": "^15.2.0",
83
+ "lint-staged": "^13.3.0",
84
+ "mocha": "^10.8.2",
85
+ "puppeteer": "^19.11.1",
86
+ "rollup": "^2.80.0",
87
+ "stylelint": "^15.11.0",
83
88
  "stylelint-config-standard": "^30.0.1",
84
- "stylelint-order": "^6.0.2",
85
- "uglify-js": "^3.17.4"
89
+ "stylelint-order": "^6.0.4",
90
+ "uglify-js": "^3.19.3"
86
91
  }
87
92
  }
package/src/index.js CHANGED
@@ -7,14 +7,15 @@ import {
7
7
  import {
8
8
  arrayBufferToDataURL,
9
9
  getAdjustedSizes,
10
+ getExif,
10
11
  imageTypeToExtension,
12
+ insertExif,
13
+ isCanvasAvailable,
11
14
  isImageType,
12
15
  isPositiveNumber,
13
16
  normalizeDecimalNumber,
14
17
  parseOrientation,
15
18
  resetAndGetOrientation,
16
- getExif,
17
- insertExif,
18
19
  } from './utilities';
19
20
 
20
21
  const { ArrayBuffer, FileReader } = WINDOW;
@@ -140,11 +141,19 @@ export default class Compressor {
140
141
  const { file, image } = this;
141
142
 
142
143
  image.onload = () => {
143
- this.draw({
144
- ...data,
145
- naturalWidth: image.naturalWidth,
146
- naturalHeight: image.naturalHeight,
147
- });
144
+ if (isCanvasAvailable()) {
145
+ this.draw({
146
+ ...data,
147
+ naturalWidth: image.naturalWidth,
148
+ naturalHeight: image.naturalHeight,
149
+ });
150
+ } else {
151
+ this.done({
152
+ naturalWidth: image.naturalWidth,
153
+ naturalHeight: image.naturalHeight,
154
+ result: null,
155
+ });
156
+ }
148
157
  };
149
158
  image.onabort = () => {
150
159
  this.fail(new Error('Aborted to load the image.'));
@@ -378,19 +387,31 @@ export default class Compressor {
378
387
  ) {
379
388
  result = file;
380
389
  } else {
381
- const date = new Date();
382
-
383
- result.lastModified = date.getTime();
384
- result.lastModifiedDate = date;
385
- result.name = file.name;
390
+ let fileName = file.name;
386
391
 
387
392
  // Convert the extension to match its type
388
- if (result.name && result.type !== file.type) {
389
- result.name = result.name.replace(
393
+ if (fileName && result.type !== file.type) {
394
+ fileName = fileName.replace(
390
395
  REGEXP_EXTENSION,
391
396
  imageTypeToExtension(result.type),
392
397
  );
393
398
  }
399
+
400
+ try {
401
+ // Convert the resulting Blob object into a File object for modern browsers.
402
+ result = new File([result], fileName, {
403
+ type: result.type,
404
+ });
405
+ } catch (error) {
406
+ // Fallback to Blob if the File constructor is not supported.
407
+ const date = new Date();
408
+
409
+ result.name = fileName;
410
+
411
+ // The last modified date is not accurate, but it's better than nothing.
412
+ result.lastModified = date.getTime();
413
+ result.lastModifiedDate = date;
414
+ }
394
415
  }
395
416
  } else {
396
417
  // Returns original file if the result is null in some cases.
package/src/utilities.js CHANGED
@@ -1,6 +1,4 @@
1
- import {
2
- WINDOW,
3
- } from './constants';
1
+ import { WINDOW } from './constants';
4
2
 
5
3
  /**
6
4
  * Check if the given value is a positive number.
@@ -68,6 +66,52 @@ export function getStringFromCharCode(dataView, start, length) {
68
66
  return str;
69
67
  }
70
68
 
69
+ /**
70
+ * Check if `canvas.getContext('2d').getImageData` is available,
71
+ * FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode (#137)
72
+ * @link https://github.com/nodeca/pica/blob/master/lib/utils.js
73
+ * @returns {boolean} Returns `true` if it is available, else `false`.
74
+ */
75
+ export function isCanvasAvailable() {
76
+ try {
77
+ const canvas = document.createElement('canvas');
78
+
79
+ canvas.width = 2;
80
+ canvas.height = 1;
81
+
82
+ const context = canvas.getContext('2d');
83
+
84
+ if (!context) return false;
85
+
86
+ // Create 2x1 image data containing RGBA values for two pixels
87
+ const imageData = context.createImageData(2, 1);
88
+
89
+ // First pixel: R=12, G=23, B=34, A=255
90
+ imageData.data[0] = 12;
91
+ imageData.data[1] = 23;
92
+ imageData.data[2] = 34;
93
+ imageData.data[3] = 255;
94
+
95
+ // Second pixel: R=45, G=56, B=67, A=255
96
+ imageData.data[4] = 45;
97
+ imageData.data[5] = 56;
98
+ imageData.data[6] = 67;
99
+ imageData.data[7] = 255;
100
+
101
+ context.putImageData(imageData, 0, 0);
102
+
103
+ const readBack = context.getImageData(0, 0, 2, 1);
104
+
105
+ // Expected pixel data (matching the written values)
106
+ const expected = [12, 23, 34, 255, 45, 56, 67, 255];
107
+
108
+ // Compare element by element to ensure write and read consistency
109
+ return readBack.data.every((value, index) => value === expected[index]);
110
+ } catch (error) {
111
+ return false;
112
+ }
113
+ }
114
+
71
115
  const { btoa } = WINDOW;
72
116
 
73
117
  /**