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