compressorjs 1.2.0 → 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.
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * Compressor.js v1.2.0
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-25T11:35:56.625Z
8
+ * Date: 2026-04-06T07:12:45.816Z
9
9
  */
10
10
 
11
11
  (function (global, factory) {
@@ -14,19 +14,71 @@
14
14
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Compressor = factory());
15
15
  })(this, (function () { 'use strict';
16
16
 
17
+ function _classCallCheck(a, n) {
18
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
19
+ }
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);
24
+ }
25
+ }
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;
30
+ }
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;
38
+ }
17
39
  function _extends() {
18
- _extends = Object.assign ? Object.assign.bind() : function (target) {
19
- for (var i = 1; i < arguments.length; i++) {
20
- var source = arguments[i];
21
- for (var key in source) {
22
- if (Object.prototype.hasOwnProperty.call(source, key)) {
23
- target[key] = source[key];
24
- }
25
- }
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]);
26
44
  }
27
- return target;
28
- };
29
- return _extends.apply(this, arguments);
45
+ return n;
46
+ }, _extends.apply(null, arguments);
47
+ }
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);
55
+ }
56
+ return t;
57
+ }
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;
68
+ }
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;
75
+ throw new TypeError("@@toPrimitive must return a primitive value.");
76
+ }
77
+ return ("string" === r ? String : Number)(t);
78
+ }
79
+ function _toPropertyKey(t) {
80
+ var i = _toPrimitive(t, "string");
81
+ return "symbol" == typeof i ? i : i + "";
30
82
  }
31
83
 
32
84
  var canvasToBlob = {exports: {}};
@@ -144,7 +196,7 @@
144
196
  })(canvasToBlob);
145
197
  var toBlob = canvasToBlob.exports;
146
198
 
147
- var isBlob = value => {
199
+ var isBlob = function isBlob(value) {
148
200
  if (typeof Blob === 'undefined') {
149
201
  return false;
150
202
  }
@@ -277,18 +329,18 @@
277
329
  error: null
278
330
  };
279
331
 
280
- const IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
281
- const WINDOW = IS_BROWSER ? window : {};
332
+ var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
333
+ var WINDOW = IS_BROWSER ? window : {};
282
334
 
283
335
  /**
284
336
  * Check if the given value is a positive number.
285
337
  * @param {*} value - The value to check.
286
338
  * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
287
339
  */
288
- const isPositiveNumber = value => value > 0 && value < Infinity;
289
- const {
290
- slice
291
- } = Array.prototype;
340
+ var isPositiveNumber = function isPositiveNumber(value) {
341
+ return value > 0 && value < Infinity;
342
+ };
343
+ var slice = Array.prototype.slice;
292
344
 
293
345
  /**
294
346
  * Convert array-like or iterable object to an array.
@@ -298,7 +350,7 @@
298
350
  function toArray(value) {
299
351
  return Array.from ? Array.from(value) : slice.call(value);
300
352
  }
301
- const REGEXP_IMAGE_TYPE = /^image\/.+$/;
353
+ var REGEXP_IMAGE_TYPE = /^image\/.+$/;
302
354
 
303
355
  /**
304
356
  * Check if the given value is a mime type of image.
@@ -315,15 +367,13 @@
315
367
  * @returns {boolean} Returns the image extension.
316
368
  */
317
369
  function imageTypeToExtension(value) {
318
- let extension = isImageType(value) ? value.substr(6) : '';
370
+ var extension = isImageType(value) ? value.substr(6) : '';
319
371
  if (extension === 'jpeg') {
320
372
  extension = 'jpg';
321
373
  }
322
- return `.${extension}`;
374
+ return ".".concat(extension);
323
375
  }
324
- const {
325
- fromCharCode
326
- } = String;
376
+ var fromCharCode = String.fromCharCode;
327
377
 
328
378
  /**
329
379
  * Get string from char code in data view.
@@ -333,17 +383,58 @@
333
383
  * @returns {string} The read result.
334
384
  */
335
385
  function getStringFromCharCode(dataView, start, length) {
336
- let str = '';
337
- let i;
386
+ var str = '';
387
+ var i;
338
388
  length += start;
339
389
  for (i = start; i < length; i += 1) {
340
390
  str += fromCharCode(dataView.getUint8(i));
341
391
  }
342
392
  return str;
343
393
  }
344
- const {
345
- btoa
346
- } = WINDOW;
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
+ }
437
+ var btoa = WINDOW.btoa;
347
438
 
348
439
  /**
349
440
  * Transform array buffer to Data URL.
@@ -352,16 +443,16 @@
352
443
  * @returns {string} The result Data URL.
353
444
  */
354
445
  function arrayBufferToDataURL(arrayBuffer, mimeType) {
355
- const chunks = [];
356
- const chunkSize = 8192;
357
- let uint8 = new Uint8Array(arrayBuffer);
446
+ var chunks = [];
447
+ var chunkSize = 8192;
448
+ var uint8 = new Uint8Array(arrayBuffer);
358
449
  while (uint8.length > 0) {
359
450
  // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
360
451
  // eslint-disable-next-line prefer-spread
361
452
  chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
362
453
  uint8 = uint8.subarray(chunkSize);
363
454
  }
364
- return `data:${mimeType};base64,${btoa(chunks.join(''))}`;
455
+ return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
365
456
  }
366
457
 
367
458
  /**
@@ -370,19 +461,19 @@
370
461
  * @returns {number} The read orientation value.
371
462
  */
372
463
  function resetAndGetOrientation(arrayBuffer) {
373
- const dataView = new DataView(arrayBuffer);
374
- let orientation;
464
+ var dataView = new DataView(arrayBuffer);
465
+ var orientation;
375
466
 
376
467
  // Ignores range error when the image does not have correct Exif information
377
468
  try {
378
- let littleEndian;
379
- let app1Start;
380
- let ifdStart;
469
+ var littleEndian;
470
+ var app1Start;
471
+ var ifdStart;
381
472
 
382
473
  // Only handle JPEG image (start by 0xFFD8)
383
474
  if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
384
- const length = dataView.byteLength;
385
- let offset = 2;
475
+ var length = dataView.byteLength;
476
+ var offset = 2;
386
477
  while (offset + 1 < length) {
387
478
  if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
388
479
  app1Start = offset;
@@ -392,14 +483,14 @@
392
483
  }
393
484
  }
394
485
  if (app1Start) {
395
- const exifIDCode = app1Start + 4;
396
- const tiffOffset = app1Start + 10;
486
+ var exifIDCode = app1Start + 4;
487
+ var tiffOffset = app1Start + 10;
397
488
  if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
398
- const endianness = dataView.getUint16(tiffOffset);
489
+ var endianness = dataView.getUint16(tiffOffset);
399
490
  littleEndian = endianness === 0x4949;
400
491
  if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
401
492
  if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
402
- const firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
493
+ var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
403
494
  if (firstIFDOffset >= 0x00000008) {
404
495
  ifdStart = tiffOffset + firstIFDOffset;
405
496
  }
@@ -408,20 +499,20 @@
408
499
  }
409
500
  }
410
501
  if (ifdStart) {
411
- const length = dataView.getUint16(ifdStart, littleEndian);
412
- let offset;
413
- let i;
414
- for (i = 0; i < length; i += 1) {
415
- offset = ifdStart + i * 12 + 2;
416
- if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
502
+ var _length = dataView.getUint16(ifdStart, littleEndian);
503
+ var _offset;
504
+ var i;
505
+ for (i = 0; i < _length; i += 1) {
506
+ _offset = ifdStart + i * 12 + 2;
507
+ if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {
417
508
  // 8 is the offset of the current tag's value
418
- offset += 8;
509
+ _offset += 8;
419
510
 
420
511
  // Get the original orientation value
421
- orientation = dataView.getUint16(offset, littleEndian);
512
+ orientation = dataView.getUint16(_offset, littleEndian);
422
513
 
423
514
  // Override the orientation with its default value
424
- dataView.setUint16(offset, 1, littleEndian);
515
+ dataView.setUint16(_offset, 1, littleEndian);
425
516
  break;
426
517
  }
427
518
  }
@@ -438,9 +529,9 @@
438
529
  * @returns {Object} The parsed result.
439
530
  */
440
531
  function parseOrientation(orientation) {
441
- let rotate = 0;
442
- let scaleX = 1;
443
- let scaleY = 1;
532
+ var rotate = 0;
533
+ var scaleX = 1;
534
+ var scaleY = 1;
444
535
  switch (orientation) {
445
536
  // Flip horizontal
446
537
  case 2:
@@ -480,12 +571,12 @@
480
571
  break;
481
572
  }
482
573
  return {
483
- rotate,
484
- scaleX,
485
- scaleY
574
+ rotate: rotate,
575
+ scaleX: scaleX,
576
+ scaleY: scaleY
486
577
  };
487
578
  }
488
- const REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
579
+ var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
489
580
 
490
581
  /**
491
582
  * Normalize decimal number.
@@ -495,7 +586,7 @@
495
586
  * @returns {number} Returns the normalized number.
496
587
  */
497
588
  function normalizeDecimalNumber(value) {
498
- let times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
589
+ var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
499
590
  return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
500
591
  }
501
592
 
@@ -506,16 +597,14 @@
506
597
  * @returns {Object} The result sizes.
507
598
  */
508
599
  function getAdjustedSizes(_ref) {
509
- let {
510
- aspectRatio,
511
- height,
512
- width
513
- } = _ref;
514
- let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
515
- const isValidWidth = isPositiveNumber(width);
516
- const isValidHeight = isPositiveNumber(height);
600
+ var aspectRatio = _ref.aspectRatio,
601
+ height = _ref.height,
602
+ width = _ref.width;
603
+ var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
604
+ var isValidWidth = isPositiveNumber(width);
605
+ var isValidHeight = isPositiveNumber(height);
517
606
  if (isValidWidth && isValidHeight) {
518
- const adjustedWidth = height * aspectRatio;
607
+ var adjustedWidth = height * aspectRatio;
519
608
  if ((type === 'contain' || type === 'none') && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
520
609
  height = width / aspectRatio;
521
610
  } else {
@@ -527,8 +616,8 @@
527
616
  width = height * aspectRatio;
528
617
  }
529
618
  return {
530
- width,
531
- height
619
+ width: width,
620
+ height: height
532
621
  };
533
622
  }
534
623
 
@@ -538,15 +627,13 @@
538
627
  * @returns {Array} The read Exif information.
539
628
  */
540
629
  function getExif(arrayBuffer) {
541
- const array = toArray(new Uint8Array(arrayBuffer));
542
- const {
543
- length
544
- } = array;
545
- const segments = [];
546
- let start = 0;
630
+ var array = toArray(new Uint8Array(arrayBuffer));
631
+ var length = array.length;
632
+ var segments = [];
633
+ var start = 0;
547
634
  while (start + 3 < length) {
548
- const value = array[start];
549
- const next = array[start + 1];
635
+ var value = array[start];
636
+ var next = array[start + 1];
550
637
 
551
638
  // SOS (Start of Scan)
552
639
  if (value === 0xFF && next === 0xDA) {
@@ -557,14 +644,14 @@
557
644
  if (value === 0xFF && next === 0xD8) {
558
645
  start += 2;
559
646
  } else {
560
- const offset = array[start + 2] * 256 + array[start + 3];
561
- const end = start + offset + 2;
562
- const segment = array.slice(start, end);
647
+ var offset = array[start + 2] * 256 + array[start + 3];
648
+ var end = start + offset + 2;
649
+ var segment = array.slice(start, end);
563
650
  segments.push(segment);
564
651
  start = end;
565
652
  }
566
653
  }
567
- return segments.reduce((exifArray, current) => {
654
+ return segments.reduce(function (exifArray, current) {
568
655
  if (current[0] === 0xFF && current[1] === 0xE1) {
569
656
  return exifArray.concat(current);
570
657
  }
@@ -579,415 +666,439 @@
579
666
  * @returns {ArrayBuffer} The transformed array buffer.
580
667
  */
581
668
  function insertExif(arrayBuffer, exifArray) {
582
- const array = toArray(new Uint8Array(arrayBuffer));
669
+ var array = toArray(new Uint8Array(arrayBuffer));
583
670
  if (array[2] !== 0xFF || array[3] !== 0xE0) {
584
671
  return arrayBuffer;
585
672
  }
586
- const app0Length = array[4] * 256 + array[5];
587
- const newArrayBuffer = [0xFF, 0xD8].concat(exifArray, array.slice(4 + app0Length));
673
+ var app0Length = array[4] * 256 + array[5];
674
+ var newArrayBuffer = [0xFF, 0xD8].concat(exifArray, array.slice(4 + app0Length));
588
675
  return new Uint8Array(newArrayBuffer);
589
676
  }
590
677
 
591
- const {
592
- ArrayBuffer: ArrayBuffer$1,
593
- FileReader
594
- } = WINDOW;
595
- const URL = WINDOW.URL || WINDOW.webkitURL;
596
- const REGEXP_EXTENSION = /\.\w+$/;
597
- const AnotherCompressor = WINDOW.Compressor;
678
+ var ArrayBuffer$1 = WINDOW.ArrayBuffer,
679
+ FileReader = WINDOW.FileReader;
680
+ var URL = WINDOW.URL || WINDOW.webkitURL;
681
+ var REGEXP_EXTENSION = /\.\w+$/;
682
+ var AnotherCompressor = WINDOW.Compressor;
598
683
 
599
684
  /**
600
685
  * Creates a new image compressor.
601
686
  * @class
602
687
  */
603
- class Compressor {
688
+ var Compressor = /*#__PURE__*/function () {
604
689
  /**
605
690
  * The constructor of Compressor.
606
691
  * @param {File|Blob} file - The target image file for compressing.
607
692
  * @param {Object} [options] - The options for compressing.
608
693
  */
609
- constructor(file, options) {
694
+ function Compressor(file, options) {
695
+ _classCallCheck(this, Compressor);
610
696
  this.file = file;
611
697
  this.exif = [];
612
698
  this.image = new Image();
613
- this.options = {
614
- ...DEFAULTS,
615
- ...options
616
- };
699
+ this.options = _objectSpread2(_objectSpread2({}, DEFAULTS), options);
617
700
  this.aborted = false;
618
701
  this.result = null;
619
702
  this.init();
620
703
  }
621
- init() {
622
- const {
623
- file,
624
- options
625
- } = this;
626
- if (!isBlob(file)) {
627
- this.fail(new Error('The first argument must be a File or Blob object.'));
628
- return;
629
- }
630
- const mimeType = file.type;
631
- if (!isImageType(mimeType)) {
632
- this.fail(new Error('The first argument must be an image File or Blob object.'));
633
- return;
634
- }
635
- if (!URL || !FileReader) {
636
- this.fail(new Error('The current browser does not support image compression.'));
637
- return;
638
- }
639
- if (!ArrayBuffer$1) {
640
- options.checkOrientation = false;
641
- options.retainExif = false;
642
- }
643
- const isJPEGImage = mimeType === 'image/jpeg';
644
- const checkOrientation = isJPEGImage && options.checkOrientation;
645
- const retainExif = isJPEGImage && options.retainExif;
646
- if (URL && !checkOrientation && !retainExif) {
647
- this.load({
648
- url: URL.createObjectURL(file)
649
- });
650
- } else {
651
- const reader = new FileReader();
652
- this.reader = reader;
653
- reader.onload = _ref => {
654
- let {
655
- target
656
- } = _ref;
657
- const {
658
- result
659
- } = target;
660
- const data = {};
661
- let orientation = 1;
662
- if (checkOrientation) {
663
- // Reset the orientation value to its default value 1
664
- // as some iOS browsers will render image with its orientation
665
- orientation = resetAndGetOrientation(result);
666
- if (orientation > 1) {
667
- _extends(data, parseOrientation(orientation));
704
+ return _createClass(Compressor, [{
705
+ key: "init",
706
+ value: function init() {
707
+ var _this = this;
708
+ var file = this.file,
709
+ options = this.options;
710
+ if (!isBlob(file)) {
711
+ this.fail(new Error('The first argument must be a File or Blob object.'));
712
+ return;
713
+ }
714
+ var mimeType = file.type;
715
+ if (!isImageType(mimeType)) {
716
+ this.fail(new Error('The first argument must be an image File or Blob object.'));
717
+ return;
718
+ }
719
+ if (!URL || !FileReader) {
720
+ this.fail(new Error('The current browser does not support image compression.'));
721
+ return;
722
+ }
723
+ if (!ArrayBuffer$1) {
724
+ options.checkOrientation = false;
725
+ options.retainExif = false;
726
+ }
727
+ var isJPEGImage = mimeType === 'image/jpeg';
728
+ var checkOrientation = isJPEGImage && options.checkOrientation;
729
+ var retainExif = isJPEGImage && options.retainExif;
730
+ if (URL && !checkOrientation && !retainExif) {
731
+ this.load({
732
+ url: URL.createObjectURL(file)
733
+ });
734
+ } else {
735
+ var reader = new FileReader();
736
+ this.reader = reader;
737
+ reader.onload = function (_ref) {
738
+ var target = _ref.target;
739
+ var result = target.result;
740
+ var data = {};
741
+ var orientation = 1;
742
+ if (checkOrientation) {
743
+ // Reset the orientation value to its default value 1
744
+ // as some iOS browsers will render image with its orientation
745
+ orientation = resetAndGetOrientation(result);
746
+ if (orientation > 1) {
747
+ _extends(data, parseOrientation(orientation));
748
+ }
668
749
  }
669
- }
670
- if (retainExif) {
671
- this.exif = getExif(result);
672
- }
673
- if (checkOrientation || retainExif) {
674
- if (!URL
750
+ if (retainExif) {
751
+ _this.exif = getExif(result);
752
+ }
753
+ if (checkOrientation || retainExif) {
754
+ if (!URL
675
755
 
676
- // Generate a new URL with the default orientation value 1.
677
- || orientation > 1) {
678
- data.url = arrayBufferToDataURL(result, mimeType);
756
+ // Generate a new URL with the default orientation value 1.
757
+ || orientation > 1) {
758
+ data.url = arrayBufferToDataURL(result, mimeType);
759
+ } else {
760
+ data.url = URL.createObjectURL(file);
761
+ }
679
762
  } else {
680
- data.url = URL.createObjectURL(file);
763
+ data.url = result;
681
764
  }
765
+ _this.load(data);
766
+ };
767
+ reader.onabort = function () {
768
+ _this.fail(new Error('Aborted to read the image with FileReader.'));
769
+ };
770
+ reader.onerror = function () {
771
+ _this.fail(new Error('Failed to read the image with FileReader.'));
772
+ };
773
+ reader.onloadend = function () {
774
+ _this.reader = null;
775
+ };
776
+ if (checkOrientation || retainExif) {
777
+ reader.readAsArrayBuffer(file);
682
778
  } else {
683
- data.url = result;
779
+ reader.readAsDataURL(file);
780
+ }
781
+ }
782
+ }
783
+ }, {
784
+ key: "load",
785
+ value: function load(data) {
786
+ var _this2 = this;
787
+ var file = this.file,
788
+ image = this.image;
789
+ image.onload = function () {
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
+ });
684
801
  }
685
- this.load(data);
686
- };
687
- reader.onabort = () => {
688
- this.fail(new Error('Aborted to read the image with FileReader.'));
689
802
  };
690
- reader.onerror = () => {
691
- this.fail(new Error('Failed to read the image with FileReader.'));
803
+ image.onabort = function () {
804
+ _this2.fail(new Error('Aborted to load the image.'));
692
805
  };
693
- reader.onloadend = () => {
694
- this.reader = null;
806
+ image.onerror = function () {
807
+ _this2.fail(new Error('Failed to load the image.'));
695
808
  };
696
- if (checkOrientation || retainExif) {
697
- reader.readAsArrayBuffer(file);
698
- } else {
699
- reader.readAsDataURL(file);
700
- }
701
- }
702
- }
703
- load(data) {
704
- const {
705
- file,
706
- image
707
- } = this;
708
- image.onload = () => {
709
- this.draw({
710
- ...data,
711
- naturalWidth: image.naturalWidth,
712
- naturalHeight: image.naturalHeight
713
- });
714
- };
715
- image.onabort = () => {
716
- this.fail(new Error('Aborted to load the image.'));
717
- };
718
- image.onerror = () => {
719
- this.fail(new Error('Failed to load the image.'));
720
- };
721
809
 
722
- // Match all browsers that use WebKit as the layout engine in iOS devices,
723
- // such as Safari for iOS, Chrome for iOS, and in-app browsers.
724
- if (WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent)) {
725
- // Fix the `The operation is insecure` error (#57)
726
- image.crossOrigin = 'anonymous';
727
- }
728
- image.alt = file.name;
729
- image.src = data.url;
730
- }
731
- draw(_ref2) {
732
- let {
733
- naturalWidth,
734
- naturalHeight,
735
- rotate = 0,
736
- scaleX = 1,
737
- scaleY = 1
738
- } = _ref2;
739
- const {
740
- file,
741
- image,
742
- options
743
- } = this;
744
- const canvas = document.createElement('canvas');
745
- const context = canvas.getContext('2d');
746
- const is90DegreesRotated = Math.abs(rotate) % 180 === 90;
747
- const resizable = (options.resize === 'contain' || options.resize === 'cover') && isPositiveNumber(options.width) && isPositiveNumber(options.height);
748
- let maxWidth = Math.max(options.maxWidth, 0) || Infinity;
749
- let maxHeight = Math.max(options.maxHeight, 0) || Infinity;
750
- let minWidth = Math.max(options.minWidth, 0) || 0;
751
- let minHeight = Math.max(options.minHeight, 0) || 0;
752
- let aspectRatio = naturalWidth / naturalHeight;
753
- let {
754
- width,
755
- height
756
- } = options;
757
- if (is90DegreesRotated) {
758
- [maxWidth, maxHeight] = [maxHeight, maxWidth];
759
- [minWidth, minHeight] = [minHeight, minWidth];
760
- [width, height] = [height, width];
761
- }
762
- if (resizable) {
763
- aspectRatio = width / height;
764
- }
765
- ({
766
- width: maxWidth,
767
- height: maxHeight
768
- } = getAdjustedSizes({
769
- aspectRatio,
770
- width: maxWidth,
771
- height: maxHeight
772
- }, 'contain'));
773
- ({
774
- width: minWidth,
775
- height: minHeight
776
- } = getAdjustedSizes({
777
- aspectRatio,
778
- width: minWidth,
779
- height: minHeight
780
- }, 'cover'));
781
- if (resizable) {
782
- ({
783
- width,
784
- height
785
- } = getAdjustedSizes({
786
- aspectRatio,
787
- width,
788
- height
789
- }, options.resize));
790
- } else {
791
- ({
792
- width = naturalWidth,
793
- height = naturalHeight
794
- } = getAdjustedSizes({
795
- aspectRatio,
796
- width,
797
- height
798
- }));
799
- }
800
- width = Math.floor(normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth)));
801
- height = Math.floor(normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight)));
802
- const destX = -width / 2;
803
- const destY = -height / 2;
804
- const destWidth = width;
805
- const destHeight = height;
806
- const params = [];
807
- if (resizable) {
808
- let srcX = 0;
809
- let srcY = 0;
810
- let srcWidth = naturalWidth;
811
- let srcHeight = naturalHeight;
812
- ({
813
- width: srcWidth,
814
- height: srcHeight
815
- } = getAdjustedSizes({
816
- aspectRatio,
817
- width: naturalWidth,
818
- height: naturalHeight
819
- }, {
820
- contain: 'cover',
821
- cover: 'contain'
822
- }[options.resize]));
823
- srcX = (naturalWidth - srcWidth) / 2;
824
- srcY = (naturalHeight - srcHeight) / 2;
825
- params.push(srcX, srcY, srcWidth, srcHeight);
826
- }
827
- params.push(destX, destY, destWidth, destHeight);
828
- if (is90DegreesRotated) {
829
- [width, height] = [height, width];
830
- }
831
- canvas.width = width;
832
- canvas.height = height;
833
- if (!isImageType(options.mimeType)) {
834
- options.mimeType = file.type;
810
+ // Match all browsers that use WebKit as the layout engine in iOS devices,
811
+ // such as Safari for iOS, Chrome for iOS, and in-app browsers.
812
+ if (WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent)) {
813
+ // Fix the `The operation is insecure` error (#57)
814
+ image.crossOrigin = 'anonymous';
815
+ }
816
+ image.alt = file.name;
817
+ image.src = data.url;
835
818
  }
836
- let fillStyle = 'transparent';
819
+ }, {
820
+ key: "draw",
821
+ value: function draw(_ref2) {
822
+ var _this3 = this;
823
+ var naturalWidth = _ref2.naturalWidth,
824
+ naturalHeight = _ref2.naturalHeight,
825
+ _ref2$rotate = _ref2.rotate,
826
+ rotate = _ref2$rotate === void 0 ? 0 : _ref2$rotate,
827
+ _ref2$scaleX = _ref2.scaleX,
828
+ scaleX = _ref2$scaleX === void 0 ? 1 : _ref2$scaleX,
829
+ _ref2$scaleY = _ref2.scaleY,
830
+ scaleY = _ref2$scaleY === void 0 ? 1 : _ref2$scaleY;
831
+ var file = this.file,
832
+ image = this.image,
833
+ options = this.options;
834
+ var canvas = document.createElement('canvas');
835
+ var context = canvas.getContext('2d');
836
+ var is90DegreesRotated = Math.abs(rotate) % 180 === 90;
837
+ var resizable = (options.resize === 'contain' || options.resize === 'cover') && isPositiveNumber(options.width) && isPositiveNumber(options.height);
838
+ var maxWidth = Math.max(options.maxWidth, 0) || Infinity;
839
+ var maxHeight = Math.max(options.maxHeight, 0) || Infinity;
840
+ var minWidth = Math.max(options.minWidth, 0) || 0;
841
+ var minHeight = Math.max(options.minHeight, 0) || 0;
842
+ var aspectRatio = naturalWidth / naturalHeight;
843
+ var width = options.width,
844
+ height = options.height;
845
+ if (is90DegreesRotated) {
846
+ var _ref3 = [maxHeight, maxWidth];
847
+ maxWidth = _ref3[0];
848
+ maxHeight = _ref3[1];
849
+ var _ref4 = [minHeight, minWidth];
850
+ minWidth = _ref4[0];
851
+ minHeight = _ref4[1];
852
+ var _ref5 = [height, width];
853
+ width = _ref5[0];
854
+ height = _ref5[1];
855
+ }
856
+ if (resizable) {
857
+ aspectRatio = width / height;
858
+ }
859
+ var _getAdjustedSizes = getAdjustedSizes({
860
+ aspectRatio: aspectRatio,
861
+ width: maxWidth,
862
+ height: maxHeight
863
+ }, 'contain');
864
+ maxWidth = _getAdjustedSizes.width;
865
+ maxHeight = _getAdjustedSizes.height;
866
+ var _getAdjustedSizes2 = getAdjustedSizes({
867
+ aspectRatio: aspectRatio,
868
+ width: minWidth,
869
+ height: minHeight
870
+ }, 'cover');
871
+ minWidth = _getAdjustedSizes2.width;
872
+ minHeight = _getAdjustedSizes2.height;
873
+ if (resizable) {
874
+ var _getAdjustedSizes3 = getAdjustedSizes({
875
+ aspectRatio: aspectRatio,
876
+ width: width,
877
+ height: height
878
+ }, options.resize);
879
+ width = _getAdjustedSizes3.width;
880
+ height = _getAdjustedSizes3.height;
881
+ } else {
882
+ var _getAdjustedSizes4 = getAdjustedSizes({
883
+ aspectRatio: aspectRatio,
884
+ width: width,
885
+ height: height
886
+ });
887
+ var _getAdjustedSizes4$wi = _getAdjustedSizes4.width;
888
+ width = _getAdjustedSizes4$wi === void 0 ? naturalWidth : _getAdjustedSizes4$wi;
889
+ var _getAdjustedSizes4$he = _getAdjustedSizes4.height;
890
+ height = _getAdjustedSizes4$he === void 0 ? naturalHeight : _getAdjustedSizes4$he;
891
+ }
892
+ width = Math.floor(normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth)));
893
+ height = Math.floor(normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight)));
894
+ var destX = -width / 2;
895
+ var destY = -height / 2;
896
+ var destWidth = width;
897
+ var destHeight = height;
898
+ var params = [];
899
+ if (resizable) {
900
+ var srcX = 0;
901
+ var srcY = 0;
902
+ var srcWidth = naturalWidth;
903
+ var srcHeight = naturalHeight;
904
+ var _getAdjustedSizes5 = getAdjustedSizes({
905
+ aspectRatio: aspectRatio,
906
+ width: naturalWidth,
907
+ height: naturalHeight
908
+ }, {
909
+ contain: 'cover',
910
+ cover: 'contain'
911
+ }[options.resize]);
912
+ srcWidth = _getAdjustedSizes5.width;
913
+ srcHeight = _getAdjustedSizes5.height;
914
+ srcX = (naturalWidth - srcWidth) / 2;
915
+ srcY = (naturalHeight - srcHeight) / 2;
916
+ params.push(srcX, srcY, srcWidth, srcHeight);
917
+ }
918
+ params.push(destX, destY, destWidth, destHeight);
919
+ if (is90DegreesRotated) {
920
+ var _ref6 = [height, width];
921
+ width = _ref6[0];
922
+ height = _ref6[1];
923
+ }
924
+ canvas.width = width;
925
+ canvas.height = height;
926
+ if (!isImageType(options.mimeType)) {
927
+ options.mimeType = file.type;
928
+ }
929
+ var fillStyle = 'transparent';
837
930
 
838
- // Converts PNG files over the `convertSize` to JPEGs.
839
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
840
- options.mimeType = 'image/jpeg';
841
- }
842
- const isJPEGImage = options.mimeType === 'image/jpeg';
843
- if (isJPEGImage) {
844
- fillStyle = '#fff';
845
- }
931
+ // Converts PNG files over the `convertSize` to JPEGs.
932
+ if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
933
+ options.mimeType = 'image/jpeg';
934
+ }
935
+ var isJPEGImage = options.mimeType === 'image/jpeg';
936
+ if (isJPEGImage) {
937
+ fillStyle = '#fff';
938
+ }
846
939
 
847
- // Override the default fill color (#000, black)
848
- context.fillStyle = fillStyle;
849
- context.fillRect(0, 0, width, height);
850
- if (options.beforeDraw) {
851
- options.beforeDraw.call(this, context, canvas);
852
- }
853
- if (this.aborted) {
854
- return;
855
- }
856
- context.save();
857
- context.translate(width / 2, height / 2);
858
- context.rotate(rotate * Math.PI / 180);
859
- context.scale(scaleX, scaleY);
860
- context.drawImage(image, ...params);
861
- context.restore();
862
- if (options.drew) {
863
- options.drew.call(this, context, canvas);
864
- }
865
- if (this.aborted) {
866
- return;
867
- }
868
- const callback = blob => {
869
- if (!this.aborted) {
870
- const done = result => this.done({
871
- naturalWidth,
872
- naturalHeight,
873
- result
874
- });
875
- if (blob && isJPEGImage && options.retainExif && this.exif && this.exif.length > 0) {
876
- const next = arrayBuffer => done(toBlob(arrayBufferToDataURL(insertExif(arrayBuffer, this.exif), options.mimeType)));
877
- if (blob.arrayBuffer) {
878
- blob.arrayBuffer().then(next).catch(() => {
879
- this.fail(new Error('Failed to read the compressed image with Blob.arrayBuffer().'));
940
+ // Override the default fill color (#000, black)
941
+ context.fillStyle = fillStyle;
942
+ context.fillRect(0, 0, width, height);
943
+ if (options.beforeDraw) {
944
+ options.beforeDraw.call(this, context, canvas);
945
+ }
946
+ if (this.aborted) {
947
+ return;
948
+ }
949
+ context.save();
950
+ context.translate(width / 2, height / 2);
951
+ context.rotate(rotate * Math.PI / 180);
952
+ context.scale(scaleX, scaleY);
953
+ context.drawImage.apply(context, [image].concat(params));
954
+ context.restore();
955
+ if (options.drew) {
956
+ options.drew.call(this, context, canvas);
957
+ }
958
+ if (this.aborted) {
959
+ return;
960
+ }
961
+ var callback = function callback(blob) {
962
+ if (!_this3.aborted) {
963
+ var done = function done(result) {
964
+ return _this3.done({
965
+ naturalWidth: naturalWidth,
966
+ naturalHeight: naturalHeight,
967
+ result: result
880
968
  });
881
- } else {
882
- const reader = new FileReader();
883
- this.reader = reader;
884
- reader.onload = _ref3 => {
885
- let {
886
- target
887
- } = _ref3;
888
- next(target.result);
889
- };
890
- reader.onabort = () => {
891
- this.fail(new Error('Aborted to read the compressed image with FileReader.'));
892
- };
893
- reader.onerror = () => {
894
- this.fail(new Error('Failed to read the compressed image with FileReader.'));
895
- };
896
- reader.onloadend = () => {
897
- this.reader = null;
969
+ };
970
+ if (blob && isJPEGImage && options.retainExif && _this3.exif && _this3.exif.length > 0) {
971
+ var next = function next(arrayBuffer) {
972
+ return done(toBlob(arrayBufferToDataURL(insertExif(arrayBuffer, _this3.exif), options.mimeType)));
898
973
  };
899
- reader.readAsArrayBuffer(blob);
974
+ if (blob.arrayBuffer) {
975
+ blob.arrayBuffer().then(next).catch(function () {
976
+ _this3.fail(new Error('Failed to read the compressed image with Blob.arrayBuffer().'));
977
+ });
978
+ } else {
979
+ var reader = new FileReader();
980
+ _this3.reader = reader;
981
+ reader.onload = function (_ref7) {
982
+ var target = _ref7.target;
983
+ next(target.result);
984
+ };
985
+ reader.onabort = function () {
986
+ _this3.fail(new Error('Aborted to read the compressed image with FileReader.'));
987
+ };
988
+ reader.onerror = function () {
989
+ _this3.fail(new Error('Failed to read the compressed image with FileReader.'));
990
+ };
991
+ reader.onloadend = function () {
992
+ _this3.reader = null;
993
+ };
994
+ reader.readAsArrayBuffer(blob);
995
+ }
996
+ } else {
997
+ done(blob);
900
998
  }
901
- } else {
902
- done(blob);
903
999
  }
1000
+ };
1001
+ if (canvas.toBlob) {
1002
+ canvas.toBlob(callback, options.mimeType, options.quality);
1003
+ } else {
1004
+ callback(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
904
1005
  }
905
- };
906
- if (canvas.toBlob) {
907
- canvas.toBlob(callback, options.mimeType, options.quality);
908
- } else {
909
- callback(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
910
- }
911
- }
912
- done(_ref4) {
913
- let {
914
- naturalWidth,
915
- naturalHeight,
916
- result
917
- } = _ref4;
918
- const {
919
- file,
920
- image,
921
- options
922
- } = this;
923
- if (URL && image.src.indexOf('blob:') === 0) {
924
- URL.revokeObjectURL(image.src);
925
1006
  }
926
- if (result) {
927
- // Returns original file if the result is greater than it and without size related options
928
- 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)) {
929
- result = file;
930
- } else {
931
- const date = new Date();
932
- result.lastModified = date.getTime();
933
- result.lastModifiedDate = date;
934
- result.name = file.name;
935
-
936
- // Convert the extension to match its type
937
- if (result.name && result.type !== file.type) {
938
- result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1007
+ }, {
1008
+ key: "done",
1009
+ value: function done(_ref8) {
1010
+ var naturalWidth = _ref8.naturalWidth,
1011
+ naturalHeight = _ref8.naturalHeight,
1012
+ result = _ref8.result;
1013
+ var file = this.file,
1014
+ image = this.image,
1015
+ options = this.options;
1016
+ if (URL && image.src.indexOf('blob:') === 0) {
1017
+ URL.revokeObjectURL(image.src);
1018
+ }
1019
+ if (result) {
1020
+ // Returns original file if the result is greater than it and without size related options
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)) {
1022
+ result = file;
1023
+ } else {
1024
+ var fileName = file.name;
1025
+
1026
+ // Convert the extension to match its 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;
1043
+ }
939
1044
  }
1045
+ } else {
1046
+ // Returns original file if the result is null in some cases.
1047
+ result = file;
1048
+ }
1049
+ this.result = result;
1050
+ if (options.success) {
1051
+ options.success.call(this, result);
940
1052
  }
941
- } else {
942
- // Returns original file if the result is null in some cases.
943
- result = file;
944
- }
945
- this.result = result;
946
- if (options.success) {
947
- options.success.call(this, result);
948
- }
949
- }
950
- fail(err) {
951
- const {
952
- options
953
- } = this;
954
- if (options.error) {
955
- options.error.call(this, err);
956
- } else {
957
- throw err;
958
1053
  }
959
- }
960
- abort() {
961
- if (!this.aborted) {
962
- this.aborted = true;
963
- if (this.reader) {
964
- this.reader.abort();
965
- } else if (!this.image.complete) {
966
- this.image.onload = null;
967
- this.image.onabort();
1054
+ }, {
1055
+ key: "fail",
1056
+ value: function fail(err) {
1057
+ var options = this.options;
1058
+ if (options.error) {
1059
+ options.error.call(this, err);
968
1060
  } else {
969
- this.fail(new Error('The compression process has been aborted.'));
1061
+ throw err;
1062
+ }
1063
+ }
1064
+ }, {
1065
+ key: "abort",
1066
+ value: function abort() {
1067
+ if (!this.aborted) {
1068
+ this.aborted = true;
1069
+ if (this.reader) {
1070
+ this.reader.abort();
1071
+ } else if (!this.image.complete) {
1072
+ this.image.onload = null;
1073
+ this.image.onabort();
1074
+ } else {
1075
+ this.fail(new Error('The compression process has been aborted.'));
1076
+ }
970
1077
  }
971
1078
  }
972
- }
973
1079
 
974
- /**
975
- * Get the no conflict compressor class.
976
- * @returns {Compressor} The compressor class.
977
- */
978
- static noConflict() {
979
- window.Compressor = AnotherCompressor;
980
- return Compressor;
981
- }
1080
+ /**
1081
+ * Get the no conflict compressor class.
1082
+ * @returns {Compressor} The compressor class.
1083
+ */
1084
+ }], [{
1085
+ key: "noConflict",
1086
+ value: function noConflict() {
1087
+ window.Compressor = AnotherCompressor;
1088
+ return Compressor;
1089
+ }
982
1090
 
983
- /**
984
- * Change the default options.
985
- * @param {Object} options - The new default options.
986
- */
987
- static setDefaults(options) {
988
- _extends(DEFAULTS, options);
989
- }
990
- }
1091
+ /**
1092
+ * Change the default options.
1093
+ * @param {Object} options - The new default options.
1094
+ */
1095
+ }, {
1096
+ key: "setDefaults",
1097
+ value: function setDefaults(options) {
1098
+ _extends(DEFAULTS, options);
1099
+ }
1100
+ }]);
1101
+ }();
991
1102
 
992
1103
  return Compressor;
993
1104