compressorjs-next 1.0.2 → 1.1.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/README.md CHANGED
@@ -22,7 +22,12 @@ A JavaScript image compressor and converter. Uses the browser’s native [HTMLCa
22
22
 
23
23
  Change the package name from `compressorjs` to `compressorjs-next` in your `package.json` and imports (`import Compressor from 'compressorjs-next'`).
24
24
 
25
- The API is otherwise the same, with these exceptions: ESM is now the default module format (CommonJS is still supported), the `noConflict()` method has been removed, and Internet Explorer is no longer supported.
25
+ The API is otherwise the same, with these exceptions (as of 1.1.0—follow [the changelog](https://github.com/j9t/compressorjs-next/blob/main/CHANGELOG.md) from there):
26
+
27
+ * ESM is now the default module format (CommonJS is still supported)
28
+ * The `noConflict()` method has been removed
29
+ * The default for `convertTypes` has changed from `['image/png']` to `[]`
30
+ * Internet Explorer is no longer supported
26
31
 
27
32
  ## Main files
28
33
 
@@ -235,12 +240,12 @@ The [MIME type](https://webglossary.info/terms/mime-type/) of the output image.
235
240
  ### `convertTypes`
236
241
 
237
242
  * Type: `Array` or `string` (multiple types should be separated by commas)
238
- * Default: `["image/png"]`
243
+ * Default: `[]`
239
244
  * Examples:
240
245
  - `["image/png", "image/webp"]`
241
246
  - `"image/png,image/webp"`
242
247
 
243
- Files whose file type is included in this list, and whose file size exceeds the `convertSize` value will be converted to JPEGs.
248
+ Files whose file type is included in this list, and whose file size exceeds the `convertSize` value will be converted to JPEG.
244
249
 
245
250
  For image file type support, see the [Image file type and format guide](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types).
246
251
 
@@ -249,7 +254,7 @@ For image file type support, see the [Image file type and format guide](https://
249
254
  * Type: `number`
250
255
  * Default: `5000000` (5 MB)
251
256
 
252
- Files whose file type is included in the `convertTypes` list, and whose file size exceeds this value will be converted to JPEGs. To disable this, just set the value to `Infinity`.
257
+ Files whose file type is included in the `convertTypes` list, and whose file size exceeds this value will be converted to JPEG. To disable this, just set the value to `Infinity`.
253
258
 
254
259
  **Examples:**
255
260
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Compressor.js Next v1.0.2
2
+ * Compressor.js Next v1.1.0
3
3
  * https://github.com/j9t/compressorjs-next
4
4
  *
5
5
  * Copyright 2018–2024 Chen Fengyuan
@@ -81,13 +81,14 @@ var DEFAULTS = {
81
81
  mimeType: 'auto',
82
82
  /**
83
83
  * Files whose file type is included in this list,
84
- * and whose file size exceeds the `convertSize` value will be converted to JPEGs.
84
+ * and whose file size exceeds the `convertSize` value will be converted to JPEG.
85
85
  * @type {string|Array}
86
86
  */
87
- convertTypes: ['image/png'],
87
+ convertTypes: [],
88
88
  /**
89
- * PNG files over this size (5 MB by default) will be converted to JPEGs.
90
- * To disable this, just set the value to `Infinity`.
89
+ * Files over this size (5 MB by default) whose type is in `convertTypes`
90
+ * will be converted to JPEG.
91
+ * To disable this, set `convertTypes` to `[]` or the value to `Infinity`.
91
92
  * @type {number}
92
93
  */
93
94
  convertSize: 5000000,
@@ -493,6 +494,7 @@ class Compressor {
493
494
  ...DEFAULTS,
494
495
  ...options
495
496
  };
497
+ this.mimeTypeSet = options && options.mimeType && isImageType(options.mimeType);
496
498
  this.aborted = false;
497
499
  this.result = null;
498
500
  this.url = null;
@@ -715,8 +717,9 @@ class Compressor {
715
717
  }
716
718
  let fillStyle = 'transparent';
717
719
 
718
- // Converts PNG files over the `convertSize` to JPEGs.
719
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
720
+ // Converts files over the `convertSize` to JPEG,
721
+ // unless the user explicitly set a `mimeType`.
722
+ if (!this.mimeTypeSet && file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
720
723
  options.mimeType = 'image/jpeg';
721
724
  }
722
725
  const isJPEGImage = options.mimeType === 'image/jpeg';
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Compressor.js Next v1.0.2
2
+ * Compressor.js Next v1.1.0
3
3
  * https://github.com/j9t/compressorjs-next
4
4
  *
5
5
  * Copyright 2018–2024 Chen Fengyuan
@@ -79,13 +79,14 @@ var DEFAULTS = {
79
79
  mimeType: 'auto',
80
80
  /**
81
81
  * Files whose file type is included in this list,
82
- * and whose file size exceeds the `convertSize` value will be converted to JPEGs.
82
+ * and whose file size exceeds the `convertSize` value will be converted to JPEG.
83
83
  * @type {string|Array}
84
84
  */
85
- convertTypes: ['image/png'],
85
+ convertTypes: [],
86
86
  /**
87
- * PNG files over this size (5 MB by default) will be converted to JPEGs.
88
- * To disable this, just set the value to `Infinity`.
87
+ * Files over this size (5 MB by default) whose type is in `convertTypes`
88
+ * will be converted to JPEG.
89
+ * To disable this, set `convertTypes` to `[]` or the value to `Infinity`.
89
90
  * @type {number}
90
91
  */
91
92
  convertSize: 5000000,
@@ -491,6 +492,7 @@ class Compressor {
491
492
  ...DEFAULTS,
492
493
  ...options
493
494
  };
495
+ this.mimeTypeSet = options && options.mimeType && isImageType(options.mimeType);
494
496
  this.aborted = false;
495
497
  this.result = null;
496
498
  this.url = null;
@@ -713,8 +715,9 @@ class Compressor {
713
715
  }
714
716
  let fillStyle = 'transparent';
715
717
 
716
- // Converts PNG files over the `convertSize` to JPEGs.
717
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
718
+ // Converts files over the `convertSize` to JPEG,
719
+ // unless the user explicitly set a `mimeType`.
720
+ if (!this.mimeTypeSet && file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
718
721
  options.mimeType = 'image/jpeg';
719
722
  }
720
723
  const isJPEGImage = options.mimeType === 'image/jpeg';
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Compressor.js Next v1.0.2
2
+ * Compressor.js Next v1.1.0
3
3
  * https://github.com/j9t/compressorjs-next
4
4
  *
5
5
  * Copyright 2018–2024 Chen Fengyuan
@@ -85,13 +85,14 @@
85
85
  mimeType: 'auto',
86
86
  /**
87
87
  * Files whose file type is included in this list,
88
- * and whose file size exceeds the `convertSize` value will be converted to JPEGs.
88
+ * and whose file size exceeds the `convertSize` value will be converted to JPEG.
89
89
  * @type {string|Array}
90
90
  */
91
- convertTypes: ['image/png'],
91
+ convertTypes: [],
92
92
  /**
93
- * PNG files over this size (5 MB by default) will be converted to JPEGs.
94
- * To disable this, just set the value to `Infinity`.
93
+ * Files over this size (5 MB by default) whose type is in `convertTypes`
94
+ * will be converted to JPEG.
95
+ * To disable this, set `convertTypes` to `[]` or the value to `Infinity`.
95
96
  * @type {number}
96
97
  */
97
98
  convertSize: 5000000,
@@ -497,6 +498,7 @@
497
498
  ...DEFAULTS,
498
499
  ...options
499
500
  };
501
+ this.mimeTypeSet = options && options.mimeType && isImageType(options.mimeType);
500
502
  this.aborted = false;
501
503
  this.result = null;
502
504
  this.url = null;
@@ -719,8 +721,9 @@
719
721
  }
720
722
  let fillStyle = 'transparent';
721
723
 
722
- // Converts PNG files over the `convertSize` to JPEGs.
723
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
724
+ // Converts files over the `convertSize` to JPEG,
725
+ // unless the user explicitly set a `mimeType`.
726
+ if (!this.mimeTypeSet && file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
724
727
  options.mimeType = 'image/jpeg';
725
728
  }
726
729
  const isJPEGImage = options.mimeType === 'image/jpeg';
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Compressor.js Next v1.0.2
2
+ * Compressor.js Next v1.1.0
3
3
  * https://github.com/j9t/compressorjs-next
4
4
  *
5
5
  * Copyright 2018–2024 Chen Fengyuan
@@ -7,4 +7,4 @@
7
7
  *
8
8
  * Released under the MIT license.
9
9
  */
10
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()}(this,function(){"use strict";var e={strict:!0,checkOrientation:!0,retainExif:!1,maxWidth:1/0,maxHeight:1/0,minWidth:0,minHeight:0,width:void 0,height:void 0,resize:"none",quality:.8,mimeType:"auto",convertTypes:["image/png"],convertSize:5e6,beforeDraw:null,drew:null,success:null,error:null};const t="undefined"!=typeof window&&void 0!==window.document?window:{},i=e=>e>0&&e<1/0,r=/^image\/.+$/;function n(e){return r.test(e)}const{fromCharCode:a}=String;const{btoa:o}=t;function s(e){const t=new DataView(e);let i;try{let e,r,n;if(255===t.getUint8(0)&&216===t.getUint8(1)){const e=t.byteLength;let i=2;for(;i+1<e;){if(255===t.getUint8(i)&&225===t.getUint8(i+1)){r=i;break}i+=1}}if(r){const i=r+10;if("Exif"===function(e,t,i){let r,n="";for(i+=t,r=t;r<i;r+=1)n+=a(e.getUint8(r));return n}(t,r+4,4)){const r=t.getUint16(i);if(e=18761===r,(e||19789===r)&&42===t.getUint16(i+2,e)){const r=t.getUint32(i+4,e);r>=8&&(n=i+r)}}}if(n){const r=t.getUint16(n,e);let a,o;for(o=0;o<r;o+=1)if(a=n+12*o+2,274===t.getUint16(a,e)){a+=8,i=t.getUint16(a,e),t.setUint16(a,1,e);break}}}catch{i=1}return i}const h=/\.\d*(?:0|9){12}\d*$/;function l(e,t=1e11){return h.test(e)?Math.round(e*t)/t:e}function c({aspectRatio:e,height:t,width:r},n="none"){const a=i(r),o=i(t);if(a&&o){const i=t*e;("contain"===n||"none"===n)&&i>r||"cover"===n&&i<r?t=r/e:r=t*e}else a?t=r/e:o&&(r=t*e);return{width:r,height:t}}const{ArrayBuffer:d,FileReader:f}=t,u=t.URL||t.webkitURL,g=/\.\w+$/;return class{constructor(t,i){this.file=t,this.exif=[],this.image=new Image,this.options={...e,...i},this.aborted=!1,this.result=null,this.url=null,this.init()}init(){const{file:e,options:t}=this;if(!(e instanceof Blob))return void this.fail(new Error("The first argument must be a File or Blob object."));const i=e.type;if(!n(i))return void this.fail(new Error("The first argument must be an image File or Blob object."));if(!u||!f)return void this.fail(new Error("The current browser does not support image compression."));d||(t.checkOrientation=!1,t.retainExif=!1);const r="image/jpeg"===i,h=r&&t.checkOrientation,l=r&&t.retainExif;if(!u||h||l){const t=new f;this.reader=t,t.onload=({target:t})=>{const{result:r}=t,n={};let c=1;h&&(c=s(r),c>1&&Object.assign(n,function(e){let t=0,i=1,r=1;switch(e){case 2:i=-1;break;case 3:t=-180;break;case 4:r=-1;break;case 5:t=90,r=-1;break;case 6:t=90;break;case 7:t=90,i=-1;break;case 8:t=-90}return{rotate:t,scaleX:i,scaleY:r}}(c))),l&&(this.exif=function(e){const t=new DataView(e),{byteLength:i}=t,r=[];let n=0;for(;n+3<i;){const e=t.getUint8(n),a=t.getUint8(n+1);if(255===e&&218===a)break;if(255===e&&216===a)n+=2;else{const o=n+t.getUint16(n+2)+2;if(255===e&&225===a)for(let e=n;e<o&&e<i;e+=1)r.push(t.getUint8(e));n=o}}return r}(r)),h||l?!u||c>1?n.url=function(e,t){const i=new Uint8Array(e),{length:r}=i;let n="";for(let e=0;e<r;e+=8192){const t=Math.min(e+8192,r);let o="";for(let r=e;r<t;r+=1)o+=a(i[r]);n+=o}return`data:${t};base64,${o(n)}`}(r,i):(this.url=u.createObjectURL(e),n.url=this.url):n.url=r,this.load(n)},t.onabort=()=>{this.fail(new Error("Aborted to read the image with FileReader."))},t.onerror=()=>{this.fail(new Error("Failed to read the image with FileReader."))},t.onloadend=()=>{this.reader=null},h||l?t.readAsArrayBuffer(e):t.readAsDataURL(e)}else this.url=u.createObjectURL(e),this.load({url:this.url})}load(e){const{file:i,image:r}=this;r.onload=()=>{this.draw({...e,naturalWidth:r.naturalWidth,naturalHeight:r.naturalHeight})},r.onabort=()=>{this.fail(new Error("Aborted to load the image."))},r.onerror=()=>{this.fail(new Error("Failed to load the image."))},t.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(t.navigator.userAgent)&&(r.crossOrigin="anonymous"),r.alt=i.name,r.src=e.url}draw({naturalWidth:e,naturalHeight:t,rotate:r=0,scaleX:a=1,scaleY:o=1}){const{file:s,image:h,options:d}=this,u=document.createElement("canvas"),g=u.getContext("2d"),m=Math.abs(r)%180==90,w=("contain"===d.resize||"cover"===d.resize)&&i(d.width)&&i(d.height);let p=Math.max(d.maxWidth,0)||1/0,b=Math.max(d.maxHeight,0)||1/0,y=Math.max(d.minWidth,0)||0,U=Math.max(d.minHeight,0)||0,x=e/t,{width:v,height:E}=d;m&&([p,b]=[b,p],[y,U]=[U,y],[v,E]=[E,v]),w&&(x=v/E),({width:p,height:b}=c({aspectRatio:x,width:p,height:b},"contain")),({width:y,height:U}=c({aspectRatio:x,width:y,height:U},"cover")),w?({width:v,height:E}=c({aspectRatio:x,width:v,height:E},d.resize)):({width:v=e,height:E=t}=c({aspectRatio:x,width:v,height:E})),v=Math.floor(l(Math.min(Math.max(v,y),p))),E=Math.floor(l(Math.min(Math.max(E,U),b)));const R=-v/2,T=-E/2,k=v,M=E,A=[];if(w){let i=0,r=0,n=e,a=t;({width:n,height:a}=c({aspectRatio:x,width:e,height:t},{contain:"cover",cover:"contain"}[d.resize])),i=(e-n)/2,r=(t-a)/2,A.push(i,r,n,a)}A.push(R,T,k,M),m&&([v,E]=[E,v]),u.width=v,u.height=E,n(d.mimeType)||(d.mimeType=s.type);let j="transparent";s.size>d.convertSize&&d.convertTypes.indexOf(d.mimeType)>=0&&(d.mimeType="image/jpeg");const B="image/jpeg"===d.mimeType;if(B&&(j="#fff"),g.fillStyle=j,g.fillRect(0,0,v,E),d.beforeDraw&&d.beforeDraw.call(this,g,u),this.aborted)return;if(g.save(),g.translate(v/2,E/2),g.rotate(r*Math.PI/180),g.scale(a,o),g.drawImage(h,...A),g.restore(),d.drew&&d.drew.call(this,g,u),this.aborted)return;u.toBlob(i=>{if(!this.aborted){const r=i=>this.done({naturalWidth:e,naturalHeight:t,result:i});if(i&&B&&d.retainExif&&this.exif&&this.exif.length>0){const e=e=>{const t=function(e,t){const i=new DataView(e),r=new Uint8Array(e);if(255!==i.getUint8(2)||224!==i.getUint8(3))return r;const n=4+i.getUint16(4),a=r.byteLength-n,o=new Uint8Array(2+t.length+a);o[0]=255,o[1]=216;for(let e=0;e<t.length;e+=1)o[2+e]=t[e];return o.set(r.subarray(n),2+t.length),o}(e,this.exif);var i,n;r((i=t,n=d.mimeType,new Blob([i],{type:n})))};if(i.arrayBuffer)i.arrayBuffer().then(e).catch(()=>{this.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))});else{const t=new f;this.reader=t,t.onload=({target:t})=>{e(t.result)},t.onabort=()=>{this.fail(new Error("Aborted to read the compressed image with FileReader."))},t.onerror=()=>{this.fail(new Error("Failed to read the compressed image with FileReader."))},t.onloadend=()=>{this.reader=null},t.readAsArrayBuffer(i)}}else r(i)}},d.mimeType,d.quality)}done({naturalWidth:e,naturalHeight:t,result:i}){const{file:r,options:a}=this;if(this.revokeUrl(),i)if(a.strict&&!a.retainExif&&i.size>r.size&&a.mimeType===r.type&&!(a.width>e||a.height>t||a.minWidth>e||a.minHeight>t||a.maxWidth<e||a.maxHeight<t))i=r;else{const e=new Date;i.lastModified=e.getTime(),i.lastModifiedDate=e,i.name=r.name,i.name&&i.type!==r.type&&(i.name=i.name.replace(g,function(e){let t=n(e)?e.slice(6):"";return"jpeg"===t&&(t="jpg"),`.${t}`}(i.type)))}else i=r;this.result=i,a.success&&a.success.call(this,i)}fail(e){const{options:t}=this;if(this.revokeUrl(),!t.error)throw e;t.error.call(this,e)}revokeUrl(){u&&this.url&&(u.revokeObjectURL(this.url),this.url=null)}abort(){this.aborted||(this.aborted=!0,this.reader?this.reader.abort():this.image.complete?this.fail(new Error("The compression process has been aborted.")):(this.image.onload=null,this.image.onerror=null,this.image.onabort=null,this.fail(new Error("Aborted to load the image."))))}static setDefaults(t){Object.assign(e,t)}}});
10
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()}(this,function(){"use strict";var e={strict:!0,checkOrientation:!0,retainExif:!1,maxWidth:1/0,maxHeight:1/0,minWidth:0,minHeight:0,width:void 0,height:void 0,resize:"none",quality:.8,mimeType:"auto",convertTypes:[],convertSize:5e6,beforeDraw:null,drew:null,success:null,error:null};const t="undefined"!=typeof window&&void 0!==window.document?window:{},i=e=>e>0&&e<1/0,r=/^image\/.+$/;function n(e){return r.test(e)}const{fromCharCode:a}=String;const{btoa:o}=t;function s(e){const t=new DataView(e);let i;try{let e,r,n;if(255===t.getUint8(0)&&216===t.getUint8(1)){const e=t.byteLength;let i=2;for(;i+1<e;){if(255===t.getUint8(i)&&225===t.getUint8(i+1)){r=i;break}i+=1}}if(r){const i=r+10;if("Exif"===function(e,t,i){let r,n="";for(i+=t,r=t;r<i;r+=1)n+=a(e.getUint8(r));return n}(t,r+4,4)){const r=t.getUint16(i);if(e=18761===r,(e||19789===r)&&42===t.getUint16(i+2,e)){const r=t.getUint32(i+4,e);r>=8&&(n=i+r)}}}if(n){const r=t.getUint16(n,e);let a,o;for(o=0;o<r;o+=1)if(a=n+12*o+2,274===t.getUint16(a,e)){a+=8,i=t.getUint16(a,e),t.setUint16(a,1,e);break}}}catch{i=1}return i}const h=/\.\d*(?:0|9){12}\d*$/;function l(e,t=1e11){return h.test(e)?Math.round(e*t)/t:e}function c({aspectRatio:e,height:t,width:r},n="none"){const a=i(r),o=i(t);if(a&&o){const i=t*e;("contain"===n||"none"===n)&&i>r||"cover"===n&&i<r?t=r/e:r=t*e}else a?t=r/e:o&&(r=t*e);return{width:r,height:t}}const{ArrayBuffer:d,FileReader:f}=t,u=t.URL||t.webkitURL,g=/\.\w+$/;return class{constructor(t,i){this.file=t,this.exif=[],this.image=new Image,this.options={...e,...i},this.mimeTypeSet=i&&i.mimeType&&n(i.mimeType),this.aborted=!1,this.result=null,this.url=null,this.init()}init(){const{file:e,options:t}=this;if(!(e instanceof Blob))return void this.fail(new Error("The first argument must be a File or Blob object."));const i=e.type;if(!n(i))return void this.fail(new Error("The first argument must be an image File or Blob object."));if(!u||!f)return void this.fail(new Error("The current browser does not support image compression."));d||(t.checkOrientation=!1,t.retainExif=!1);const r="image/jpeg"===i,h=r&&t.checkOrientation,l=r&&t.retainExif;if(!u||h||l){const t=new f;this.reader=t,t.onload=({target:t})=>{const{result:r}=t,n={};let c=1;h&&(c=s(r),c>1&&Object.assign(n,function(e){let t=0,i=1,r=1;switch(e){case 2:i=-1;break;case 3:t=-180;break;case 4:r=-1;break;case 5:t=90,r=-1;break;case 6:t=90;break;case 7:t=90,i=-1;break;case 8:t=-90}return{rotate:t,scaleX:i,scaleY:r}}(c))),l&&(this.exif=function(e){const t=new DataView(e),{byteLength:i}=t,r=[];let n=0;for(;n+3<i;){const e=t.getUint8(n),a=t.getUint8(n+1);if(255===e&&218===a)break;if(255===e&&216===a)n+=2;else{const o=n+t.getUint16(n+2)+2;if(255===e&&225===a)for(let e=n;e<o&&e<i;e+=1)r.push(t.getUint8(e));n=o}}return r}(r)),h||l?!u||c>1?n.url=function(e,t){const i=new Uint8Array(e),{length:r}=i;let n="";for(let e=0;e<r;e+=8192){const t=Math.min(e+8192,r);let o="";for(let r=e;r<t;r+=1)o+=a(i[r]);n+=o}return`data:${t};base64,${o(n)}`}(r,i):(this.url=u.createObjectURL(e),n.url=this.url):n.url=r,this.load(n)},t.onabort=()=>{this.fail(new Error("Aborted to read the image with FileReader."))},t.onerror=()=>{this.fail(new Error("Failed to read the image with FileReader."))},t.onloadend=()=>{this.reader=null},h||l?t.readAsArrayBuffer(e):t.readAsDataURL(e)}else this.url=u.createObjectURL(e),this.load({url:this.url})}load(e){const{file:i,image:r}=this;r.onload=()=>{this.draw({...e,naturalWidth:r.naturalWidth,naturalHeight:r.naturalHeight})},r.onabort=()=>{this.fail(new Error("Aborted to load the image."))},r.onerror=()=>{this.fail(new Error("Failed to load the image."))},t.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(t.navigator.userAgent)&&(r.crossOrigin="anonymous"),r.alt=i.name,r.src=e.url}draw({naturalWidth:e,naturalHeight:t,rotate:r=0,scaleX:a=1,scaleY:o=1}){const{file:s,image:h,options:d}=this,u=document.createElement("canvas"),g=u.getContext("2d"),m=Math.abs(r)%180==90,w=("contain"===d.resize||"cover"===d.resize)&&i(d.width)&&i(d.height);let p=Math.max(d.maxWidth,0)||1/0,b=Math.max(d.maxHeight,0)||1/0,y=Math.max(d.minWidth,0)||0,U=Math.max(d.minHeight,0)||0,x=e/t,{width:v,height:T}=d;m&&([p,b]=[b,p],[y,U]=[U,y],[v,T]=[T,v]),w&&(x=v/T),({width:p,height:b}=c({aspectRatio:x,width:p,height:b},"contain")),({width:y,height:U}=c({aspectRatio:x,width:y,height:U},"cover")),w?({width:v,height:T}=c({aspectRatio:x,width:v,height:T},d.resize)):({width:v=e,height:T=t}=c({aspectRatio:x,width:v,height:T})),v=Math.floor(l(Math.min(Math.max(v,y),p))),T=Math.floor(l(Math.min(Math.max(T,U),b)));const E=-v/2,R=-T/2,k=v,M=T,A=[];if(w){let i=0,r=0,n=e,a=t;({width:n,height:a}=c({aspectRatio:x,width:e,height:t},{contain:"cover",cover:"contain"}[d.resize])),i=(e-n)/2,r=(t-a)/2,A.push(i,r,n,a)}A.push(E,R,k,M),m&&([v,T]=[T,v]),u.width=v,u.height=T,n(d.mimeType)||(d.mimeType=s.type);let j="transparent";!this.mimeTypeSet&&s.size>d.convertSize&&d.convertTypes.indexOf(d.mimeType)>=0&&(d.mimeType="image/jpeg");const B="image/jpeg"===d.mimeType;if(B&&(j="#fff"),g.fillStyle=j,g.fillRect(0,0,v,T),d.beforeDraw&&d.beforeDraw.call(this,g,u),this.aborted)return;if(g.save(),g.translate(v/2,T/2),g.rotate(r*Math.PI/180),g.scale(a,o),g.drawImage(h,...A),g.restore(),d.drew&&d.drew.call(this,g,u),this.aborted)return;u.toBlob(i=>{if(!this.aborted){const r=i=>this.done({naturalWidth:e,naturalHeight:t,result:i});if(i&&B&&d.retainExif&&this.exif&&this.exif.length>0){const e=e=>{const t=function(e,t){const i=new DataView(e),r=new Uint8Array(e);if(255!==i.getUint8(2)||224!==i.getUint8(3))return r;const n=4+i.getUint16(4),a=r.byteLength-n,o=new Uint8Array(2+t.length+a);o[0]=255,o[1]=216;for(let e=0;e<t.length;e+=1)o[2+e]=t[e];return o.set(r.subarray(n),2+t.length),o}(e,this.exif);var i,n;r((i=t,n=d.mimeType,new Blob([i],{type:n})))};if(i.arrayBuffer)i.arrayBuffer().then(e).catch(()=>{this.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))});else{const t=new f;this.reader=t,t.onload=({target:t})=>{e(t.result)},t.onabort=()=>{this.fail(new Error("Aborted to read the compressed image with FileReader."))},t.onerror=()=>{this.fail(new Error("Failed to read the compressed image with FileReader."))},t.onloadend=()=>{this.reader=null},t.readAsArrayBuffer(i)}}else r(i)}},d.mimeType,d.quality)}done({naturalWidth:e,naturalHeight:t,result:i}){const{file:r,options:a}=this;if(this.revokeUrl(),i)if(a.strict&&!a.retainExif&&i.size>r.size&&a.mimeType===r.type&&!(a.width>e||a.height>t||a.minWidth>e||a.minHeight>t||a.maxWidth<e||a.maxHeight<t))i=r;else{const e=new Date;i.lastModified=e.getTime(),i.lastModifiedDate=e,i.name=r.name,i.name&&i.type!==r.type&&(i.name=i.name.replace(g,function(e){let t=n(e)?e.slice(6):"";return"jpeg"===t&&(t="jpg"),`.${t}`}(i.type)))}else i=r;this.result=i,a.success&&a.success.call(this,i)}fail(e){const{options:t}=this;if(this.revokeUrl(),!t.error)throw e;t.error.call(this,e)}revokeUrl(){u&&this.url&&(u.revokeObjectURL(this.url),this.url=null)}abort(){this.aborted||(this.aborted=!0,this.reader?this.reader.abort():this.image.complete?this.fail(new Error("The compression process has been aborted.")):(this.image.onload=null,this.image.onerror=null,this.image.onabort=null,this.fail(new Error("Aborted to load the image."))))}static setDefaults(t){Object.assign(e,t)}}});
package/package.json CHANGED
@@ -92,5 +92,5 @@
92
92
  "sideEffects": false,
93
93
  "type": "module",
94
94
  "types": "types/index.d.ts",
95
- "version": "1.0.2"
95
+ "version": "1.1.0"
96
96
  }
package/src/defaults.js CHANGED
@@ -82,14 +82,15 @@ export default {
82
82
 
83
83
  /**
84
84
  * Files whose file type is included in this list,
85
- * and whose file size exceeds the `convertSize` value will be converted to JPEGs.
85
+ * and whose file size exceeds the `convertSize` value will be converted to JPEG.
86
86
  * @type {string|Array}
87
87
  */
88
- convertTypes: ['image/png'],
88
+ convertTypes: [],
89
89
 
90
90
  /**
91
- * PNG files over this size (5 MB by default) will be converted to JPEGs.
92
- * To disable this, just set the value to `Infinity`.
91
+ * Files over this size (5 MB by default) whose type is in `convertTypes`
92
+ * will be converted to JPEG.
93
+ * To disable this, set `convertTypes` to `[]` or the value to `Infinity`.
93
94
  * @type {number}
94
95
  */
95
96
  convertSize: 5000000,
package/src/index.js CHANGED
@@ -38,6 +38,7 @@ export default class Compressor {
38
38
  ...DEFAULTS,
39
39
  ...options,
40
40
  };
41
+ this.mimeTypeSet = options && options.mimeType && isImageType(options.mimeType);
41
42
  this.aborted = false;
42
43
  this.result = null;
43
44
  this.url = null;
@@ -263,8 +264,10 @@ export default class Compressor {
263
264
 
264
265
  let fillStyle = 'transparent';
265
266
 
266
- // Converts PNG files over the `convertSize` to JPEGs.
267
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
267
+ // Converts files over the `convertSize` to JPEG,
268
+ // unless the user explicitly set a `mimeType`.
269
+ if (!this.mimeTypeSet && file.size > options.convertSize
270
+ && options.convertTypes.indexOf(options.mimeType) >= 0) {
268
271
  options.mimeType = 'image/jpeg';
269
272
  }
270
273