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