compressorjs 1.1.1 → 1.2.1

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,10 +1,10 @@
1
1
  /*!
2
- * Compressor.js v1.1.1
2
+ * Compressor.js v1.2.1
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: 2021-10-05T02:32:40.212Z
8
+ * Date: 2023-02-28T14:09:41.732Z
9
9
  */
10
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()}(this,function(){"use strict";function t(t,e){var r,i=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),i.push.apply(i,r)),i}function a(i){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?t(Object(a),!0).forEach(function(e){var t,r;t=i,e=a[r=e],r in t?Object.defineProperty(t,r,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[r]=e}):Object.getOwnPropertyDescriptors?Object.defineProperties(i,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(a,e))})}return i}function n(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function s(){return(s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r,i=arguments[t];for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r])}return e}).apply(this,arguments)}var e,r,o,l,c,h,u,f,i={exports:{}};e=i,"undefined"!=typeof window&&(o=(r=window).HTMLCanvasElement&&r.HTMLCanvasElement.prototype,l=r.Blob&&function(){try{return Boolean(new Blob)}catch(e){return!1}}(),c=l&&r.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(e){return!1}}(),h=r.BlobBuilder||r.WebKitBlobBuilder||r.MozBlobBuilder||r.MSBlobBuilder,u=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,f=(l||h)&&r.atob&&r.ArrayBuffer&&r.Uint8Array&&function(e){var t,r,i,a,n,o=e.match(u);if(!o)throw new Error("invalid data URI");for(t=o[2]?o[1]:"text/plain"+(o[3]||";charset=US-ASCII"),i=!!o[4],o=e.slice(o[0].length),r=(i?atob:decodeURIComponent)(o),i=new ArrayBuffer(r.length),a=new Uint8Array(i),n=0;n<r.length;n+=1)a[n]=r.charCodeAt(n);return l?new Blob([c?a:i],{type:t}):((o=new h).append(i),o.getBlob(t))},r.HTMLCanvasElement&&!o.toBlob&&(o.mozGetAsFile?o.toBlob=function(e,t,r){var i=this;setTimeout(function(){r&&o.toDataURL&&f?e(f(i.toDataURL(t,r))):e(i.mozGetAsFile("blob",t))})}:o.toDataURL&&f&&(o.msToBlob?o.toBlob=function(e,t,r){var i=this;setTimeout(function(){(t&&"image/png"!==t||r)&&o.toDataURL&&f?e(f(i.toDataURL(t,r))):e(i.msToBlob(t))})}:o.toBlob=function(e,t,r){var i=this;setTimeout(function(){e(f(i.toDataURL(t,r)))})})),e.exports?e.exports=f:r.dataURLtoBlob=f);function j(e){return 0<e&&e<1/0}var T=i.exports,d={strict:!0,checkOrientation:!0,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},m="undefined"!=typeof window&&void 0!==window.document?window:{},p=Array.prototype.slice;var b=/^image\/.+$/;function R(e){return b.test(e)}var g=String.fromCharCode;var y=m.btoa;function w(e,t){for(var r,i=[],a=new Uint8Array(e);0<a.length;)i.push(g.apply(null,(r=a.subarray(0,8192),Array.from?Array.from(r):p.call(r)))),a=a.subarray(8192);return"data:".concat(t,";base64,").concat(y(i.join("")))}function v(e){var t,r,i,a,n,o,s,l=new DataView(e);try{if(255===l.getUint8(0)&&216===l.getUint8(1))for(var c=l.byteLength,h=2;h+1<c;){if(255===l.getUint8(h)&&225===l.getUint8(h+1)){r=h;break}h+=1}if(r&&(a=r+10,"Exif"===function(e,t,r){var i,a="";for(r+=t,i=t;i<r;i+=1)a+=g(e.getUint8(i));return a}(l,r+4,4)&&(!(s=18761===(n=l.getUint16(a)))&&19789!==n||42!==l.getUint16(a+2,s)||8<=(o=l.getUint32(a+4,s))&&(i=a+o))),i)for(var u,f=l.getUint16(i,s),d=0;d<f;d+=1)if(u=i+12*d+2,274===l.getUint16(u,s)){u+=8,t=l.getUint16(u,s),l.setUint16(u,1,s);break}}catch(e){t=1}return t}var U=/\.\d*(?:0|9){12}\d*$/;function k(e,t){t=1<arguments.length&&void 0!==t?t:1e11;return U.test(e)?Math.round(e*t)/t:e}function x(e,t){var r=e.aspectRatio,i=e.height,a=e.width,n=1<arguments.length&&void 0!==t?t:"none",o=j(a),e=j(i);return o&&e?(t=i*r,("contain"===n||"none"===n)&&a<t||"cover"===n&&t<a?i=a/r:a=i*r):o?i=a/r:e&&(a=i*r),{width:a,height:i}}var O=m.ArrayBuffer,B=m.FileReader,A=m.URL||m.webkitURL,M=/\.\w+$/,D=m.Compressor;return function(){function r(e,t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,r),this.file=e,this.image=new Image,this.options=a(a({},d),t),this.aborted=!1,this.result=null,this.init()}var e,t,i;return e=r,i=[{key:"noConflict",value:function(){return window.Compressor=D,r}},{key:"setDefaults",value:function(e){s(d,e)}}],(t=[{key:"init",value:function(){var i,e,a,n=this,o=this.file,t=this.options;e=o,"undefined"!=typeof Blob&&(e instanceof Blob||"[object Blob]"===Object.prototype.toString.call(e))?R(i=o.type)?A&&B?(O||(t.checkOrientation=!1),A&&!t.checkOrientation?this.load({url:A.createObjectURL(o)}):(e=new B,a=t.checkOrientation&&"image/jpeg"===i,(this.reader=e).onload=function(e){var t=e.target.result,r={};a?1<(e=v(t))||!A?(r.url=w(t,i),1<e&&s(r,function(e){var t=0,r=1,i=1;switch(e){case 2:r=-1;break;case 3:t=-180;break;case 4:i=-1;break;case 5:t=90,i=-1;break;case 6:t=90;break;case 7:t=90,r=-1;break;case 8:t=-90}return{rotate:t,scaleX:r,scaleY:i}}(e))):r.url=A.createObjectURL(o):r.url=t,n.load(r)},e.onabort=function(){n.fail(new Error("Aborted to read the image with FileReader."))},e.onerror=function(){n.fail(new Error("Failed to read the image with FileReader."))},e.onloadend=function(){n.reader=null},a?e.readAsArrayBuffer(o):e.readAsDataURL(o))):this.fail(new Error("The current browser does not support image compression.")):this.fail(new Error("The first argument must be an image File or Blob object.")):this.fail(new Error("The first argument must be a File or Blob object."))}},{key:"load",value:function(e){var t=this,r=this.file,i=this.image;i.onload=function(){t.draw(a(a({},e),{},{naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight}))},i.onabort=function(){t.fail(new Error("Aborted to load the image."))},i.onerror=function(){t.fail(new Error("Failed to load the image."))},m.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(m.navigator.userAgent)&&(i.crossOrigin="anonymous"),i.alt=r.name,i.src=e.url}},{key:"draw",value:function(e){var t=this,r=e.naturalWidth,i=e.naturalHeight,a=e.rotate,n=void 0===a?0:a,o=e.scaleX,s=void 0===o?1:o,l=e.scaleY,c=void 0===l?1:l,h=this.file,u=this.image,f=this.options,d=document.createElement("canvas"),m=d.getContext("2d"),p=Math.abs(n)%180==90,b=("contain"===f.resize||"cover"===f.resize)&&j(f.width)&&j(f.height),g=Math.max(f.maxWidth,0)||1/0,y=Math.max(f.maxHeight,0)||1/0,w=Math.max(f.minWidth,0)||0,a=Math.max(f.minHeight,0)||0,o=r/i,e=f.width,l=f.height;p&&(g=(v=[y,g])[0],y=v[1],w=(v=[a,w])[0],a=v[1],e=(v=[l,e])[0],l=v[1]);var v=x({aspectRatio:o=b?e/l:o,width:g,height:y},"contain");g=v.width,y=v.height;v=x({aspectRatio:o,width:w,height:a},"cover");w=v.width,a=v.height,l=b?(e=(v=x({aspectRatio:o,width:e,height:l},f.resize)).width,v.height):(e=void 0===(O=(U=x({aspectRatio:o,width:e,height:l})).width)?r:O,void 0===(O=U.height)?i:O);var U=-(e=Math.floor(k(Math.min(Math.max(e,w),g))))/2,O=-(l=Math.floor(k(Math.min(Math.max(l,a),y))))/2,w=e,g=l,a=[];b&&(y=(o=x({aspectRatio:o,width:y=r,height:b=i},{contain:"cover",cover:"contain"}[f.resize])).width,b=o.height,a.push((r-y)/2,(i-b)/2,y,b)),a.push(U,O,w,g),p&&(e=(B=[l,e])[0],l=B[1]),d.width=e,d.height=l,R(f.mimeType)||(f.mimeType=h.type);var B="transparent";h.size>f.convertSize&&0<=f.convertTypes.indexOf(f.mimeType)&&(f.mimeType="image/jpeg"),"image/jpeg"===f.mimeType&&(B="#fff"),m.fillStyle=B,m.fillRect(0,0,e,l),f.beforeDraw&&f.beforeDraw.call(this,m,d),this.aborted||(m.save(),m.translate(e/2,l/2),m.rotate(n*Math.PI/180),m.scale(s,c),m.drawImage.apply(m,[u].concat(a)),m.restore(),f.drew&&f.drew.call(this,m,d),this.aborted||(m=function(e){t.aborted||t.done({naturalWidth:r,naturalHeight:i,result:e})},d.toBlob?d.toBlob(m,f.mimeType,f.quality):m(T(d.toDataURL(f.mimeType,f.quality)))))}},{key:"done",value:function(e){var t=e.naturalWidth,r=e.naturalHeight,i=e.result,a=this.file,n=this.image,e=this.options;A&&!e.checkOrientation&&A.revokeObjectURL(n.src),!i||e.strict&&i.size>a.size&&e.mimeType===a.type&&!(e.width>t||e.height>r||e.minWidth>t||e.minHeight>r||e.maxWidth<t||e.maxHeight<r)?i=a:(r=new Date,i.lastModified=r.getTime(),i.lastModifiedDate=r,i.name=a.name,i.name&&i.type!==a.type&&(i.name=i.name.replace(M,(a=R(a=i.type)?a.substr(6):"",".".concat(a="jpeg"===a?"jpg":a))))),this.result=i,e.success&&e.success.call(this,i)}},{key:"fail",value:function(e){var t=this.options;if(!t.error)throw e;t.error.call(this,e)}},{key:"abort",value:function(){this.aborted||(this.aborted=!0,this.reader?this.reader.abort():this.image.complete?this.fail(new Error("The compression process has been aborted.")):(this.image.onload=null,this.image.onabort()))}}])&&n(e.prototype,t),i&&n(e,i),r}()});
10
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()}(this,function(){"use strict";function t(t,e){var r,i=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),i.push.apply(i,r)),i}function n(i){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?t(Object(n),!0).forEach(function(e){var t,r;t=i,r=n[e=e],(e=o(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r}):Object.getOwnPropertyDescriptors?Object.defineProperties(i,Object.getOwnPropertyDescriptors(n)):t(Object(n)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(n,e))})}return i}function a(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,o(i.key),i)}}function s(){return(s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r,i=arguments[t];for(r in i)Object.prototype.hasOwnProperty.call(i,r)&&(e[r]=i[r])}return e}).apply(this,arguments)}function o(e){e=function(e,t){if("object"!=typeof e||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0===r)return("string"===t?String:Number)(e);if("object"!=typeof(r=r.call(e,t||"default")))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}(e,"string");return"symbol"==typeof e?e:String(e)}function O(e){return 0<e&&e<1/0}var e,r,l,c,h,u,f,d,i={exports:{}},j=(e=i,"undefined"!=typeof window&&(l=(r=window).HTMLCanvasElement&&r.HTMLCanvasElement.prototype,c=r.Blob&&function(){try{return Boolean(new Blob)}catch(e){return!1}}(),h=c&&r.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(e){return!1}}(),u=r.BlobBuilder||r.WebKitBlobBuilder||r.MozBlobBuilder||r.MSBlobBuilder,f=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,d=(c||u)&&r.atob&&r.ArrayBuffer&&r.Uint8Array&&function(e){var t,r,i,n,a,o=e.match(f);if(!o)throw new Error("invalid data URI");for(t=o[2]?o[1]:"text/plain"+(o[3]||";charset=US-ASCII"),a=!!o[4],e=e.slice(o[0].length),r=(a?atob:decodeURIComponent)(e),o=new ArrayBuffer(r.length),i=new Uint8Array(o),n=0;n<r.length;n+=1)i[n]=r.charCodeAt(n);return c?new Blob([h?i:o],{type:t}):((a=new u).append(o),a.getBlob(t))},r.HTMLCanvasElement&&!l.toBlob&&(l.mozGetAsFile?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){r&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.mozGetAsFile("blob",t))})}:l.toDataURL&&d&&(l.msToBlob?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){(t&&"image/png"!==t||r)&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.msToBlob(t))})}:l.toBlob=function(e,t,r){var i=this;setTimeout(function(){e(d(i.toDataURL(t,r)))})})),e.exports?e.exports=d:r.dataURLtoBlob=d),i.exports),m={strict:!0,checkOrientation:!0,retainExif:!1,maxWidth:1/0,maxHeight:1/0,minWidth:0,minHeight:0,width:void 0,height:void 0,resize:"none",quality:.8,mimeType:"auto",convertTypes:["image/png"],convertSize:5e6,beforeDraw:null,drew:null,success:null,error:null},b="undefined"!=typeof window&&void 0!==window.document?window:{},p=Array.prototype.slice;function x(e){return Array.from?Array.from(e):p.call(e)}var g=/^image\/.+$/;function T(e){return g.test(e)}var y=String.fromCharCode;var w=b.btoa;function A(e,t){for(var r=[],i=new Uint8Array(e);0<i.length;)r.push(y.apply(null,x(i.subarray(0,8192)))),i=i.subarray(8192);return"data:".concat(t,";base64,").concat(w(r.join("")))}function v(e){var t,r,i,n,a,o,l,s=new DataView(e);try{if(255===s.getUint8(0)&&216===s.getUint8(1))for(var c=s.byteLength,h=2;h+1<c;){if(255===s.getUint8(h)&&225===s.getUint8(h+1)){r=h;break}h+=1}if(i=r&&(n=r+10,"Exif"===function(e,t,r){var i,n="";for(r+=t,i=t;i<r;i+=1)n+=y(e.getUint8(i));return n}(s,r+4,4))&&((l=18761===(a=s.getUint16(n)))||19789===a)&&42===s.getUint16(n+2,l)&&8<=(o=s.getUint32(n+4,l))?n+o:i)for(var u,f=s.getUint16(i,l),d=0;d<f;d+=1)if(u=i+12*d+2,274===s.getUint16(u,l)){u+=8,t=s.getUint16(u,l),s.setUint16(u,1,l);break}}catch(e){t=1}return t}var B=/\.\d*(?:0|9){12}\d*$/;function R(e,t){t=1<arguments.length&&void 0!==t?t:1e11;return B.test(e)?Math.round(e*t)/t:e}function E(e,t){var r,i=e.aspectRatio,n=e.height,e=e.width,t=1<arguments.length&&void 0!==t?t:"none",a=O(e),o=O(n);return a&&o?(r=n*i,("contain"===t||"none"===t)&&e<r||"cover"===t&&r<e?n=e/i:e=n*i):a?n=e/i:o&&(e=n*i),{width:e,height:n}}var U=b.ArrayBuffer,k=b.FileReader,M=b.URL||b.webkitURL,D=/\.\w+$/,L=b.Compressor;return function(){function r(e,t){if(!(this instanceof r))throw new TypeError("Cannot call a class as a function");this.file=e,this.exif=[],this.image=new Image,this.options=n(n({},m),t),this.aborted=!1,this.result=null,this.init()}var e,t,i;return e=r,i=[{key:"noConflict",value:function(){return window.Compressor=L,r}},{key:"setDefaults",value:function(e){s(m,e)}}],(t=[{key:"init",value:function(){var i,n,a,e,o=this,l=this.file,t=this.options;e=l,"undefined"!=typeof Blob&&(e instanceof Blob||"[object Blob]"===Object.prototype.toString.call(e))?T(i=l.type)?M&&k?(U||(t.checkOrientation=!1,t.retainExif=!1),n=(e="image/jpeg"===i)&&t.checkOrientation,a=e&&t.retainExif,!M||n||a?(e=new k,(this.reader=e).onload=function(e){var e=e.target.result,t={},r=1;n&&1<(r=v(e))&&s(t,function(e){var t=0,r=1,i=1;switch(e){case 2:r=-1;break;case 3:t=-180;break;case 4:i=-1;break;case 5:t=90,i=-1;break;case 6:t=90;break;case 7:t=90,r=-1;break;case 8:t=-90}return{rotate:t,scaleX:r,scaleY:i}}(r)),a&&(o.exif=function(e){for(var t=x(new Uint8Array(e)),r=t.length,i=[],n=0;n+3<r;){var a=t[n],o=t[n+1];if(255===a&&218===o)break;255===a&&216===o?n+=2:(a=n+(256*t[n+2]+t[n+3])+2,o=t.slice(n,a),i.push(o),n=a)}return i.reduce(function(e,t){return 255===t[0]&&225===t[1]?e.concat(t):e},[])}(e)),t.url=n||a?!M||1<r?A(e,i):M.createObjectURL(l):e,o.load(t)},e.onabort=function(){o.fail(new Error("Aborted to read the image with FileReader."))},e.onerror=function(){o.fail(new Error("Failed to read the image with FileReader."))},e.onloadend=function(){o.reader=null},n||a?e.readAsArrayBuffer(l):e.readAsDataURL(l)):this.load({url:M.createObjectURL(l)})):this.fail(new Error("The current browser does not support image compression.")):this.fail(new Error("The first argument must be an image File or Blob object.")):this.fail(new Error("The first argument must be a File or Blob object."))}},{key:"load",value:function(e){var t=this,r=this.file,i=this.image;i.onload=function(){t.draw(n(n({},e),{},{naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight}))},i.onabort=function(){t.fail(new Error("Aborted to load the image."))},i.onerror=function(){t.fail(new Error("Failed to load the image."))},b.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(b.navigator.userAgent)&&(i.crossOrigin="anonymous"),i.alt=r.name,i.src=e.url}},{key:"draw",value:function(e){var n=this,a=e.naturalWidth,o=e.naturalHeight,t=e.rotate,t=void 0===t?0:t,r=e.scaleX,r=void 0===r?1:r,e=e.scaleY,e=void 0===e?1:e,i=this.file,l=this.image,s=this.options,c=document.createElement("canvas"),h=c.getContext("2d"),u=Math.abs(t)%180==90,f=("contain"===s.resize||"cover"===s.resize)&&O(s.width)&&O(s.height),d=Math.max(s.maxWidth,0)||1/0,m=Math.max(s.maxHeight,0)||1/0,b=Math.max(s.minWidth,0)||0,p=Math.max(s.minHeight,0)||0,g=a/o,y=s.width,w=s.height,v=(u&&(d=(v=[m,d])[0],m=v[1],b=(v=[p,b])[0],p=v[1],y=(v=[w,y])[0],w=v[1]),E({aspectRatio:g=f?y/w:g,width:d,height:m},"contain")),v=(d=v.width,m=v.height,E({aspectRatio:g,width:b,height:p},"cover")),v=(b=v.width,p=v.height,w=f?(y=(v=E({aspectRatio:g,width:y,height:w},s.resize)).width,v.height):(y=void 0===(B=(v=E({aspectRatio:g,width:y,height:w})).width)?a:B,void 0===(B=v.height)?o:B),-(y=Math.floor(R(Math.min(Math.max(y,b),d))))/2),B=-(w=Math.floor(R(Math.min(Math.max(w,p),m))))/2,b=y,d=w,p=[],m=(f&&(0,m=(g=E({aspectRatio:g,width:m=a,height:f=o},{contain:"cover",cover:"contain"}[s.resize])).width,f=g.height,p.push((a-m)/2,(o-f)/2,m,f)),p.push(v,B,b,d),u&&(y=(g=[w,y])[0],w=g[1]),c.width=y,c.height=w,T(s.mimeType)||(s.mimeType=i.type),"transparent"),U=(i.size>s.convertSize&&0<=s.convertTypes.indexOf(s.mimeType)&&(s.mimeType="image/jpeg"),"image/jpeg"===s.mimeType);h.fillStyle=m=U?"#fff":m,h.fillRect(0,0,y,w),s.beforeDraw&&s.beforeDraw.call(this,h,c),this.aborted||(h.save(),h.translate(y/2,w/2),h.rotate(t*Math.PI/180),h.scale(r,e),h.drawImage.apply(h,[l].concat(p)),h.restore(),s.drew&&s.drew.call(this,h,c),this.aborted)||(f=function(e){var i,t,r;n.aborted||(i=function(e){return n.done({naturalWidth:a,naturalHeight:o,result:e})},e&&U&&s.retainExif&&n.exif&&0<n.exif.length?(t=function(e){return i(j(A((e=e,t=n.exif,255!==(r=x(new Uint8Array(e)))[2]||224!==r[3]?e:(e=256*r[4]+r[5],t=[255,216].concat(t,r.slice(4+e)),new Uint8Array(t))),s.mimeType)));var t,r},e.arrayBuffer?e.arrayBuffer().then(t).catch(function(){n.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))}):(r=new k,(n.reader=r).onload=function(e){e=e.target;t(e.result)},r.onabort=function(){n.fail(new Error("Aborted to read the compressed image with FileReader."))},r.onerror=function(){n.fail(new Error("Failed to read the compressed image with FileReader."))},r.onloadend=function(){n.reader=null},r.readAsArrayBuffer(e))):i(e))},c.toBlob?c.toBlob(f,s.mimeType,s.quality):f(j(c.toDataURL(s.mimeType,s.quality))))}},{key:"done",value:function(e){var t=e.naturalWidth,r=e.naturalHeight,e=e.result,i=this.file,n=this.image,a=this.options;M&&0===n.src.indexOf("blob:")&&M.revokeObjectURL(n.src),!e||a.strict&&!a.retainExif&&e.size>i.size&&a.mimeType===i.type&&!(a.width>t||a.height>r||a.minWidth>t||a.minHeight>r||a.maxWidth<t||a.maxHeight<r)?e=i:(n=new Date,e.lastModified=n.getTime(),e.lastModifiedDate=n,e.name=i.name,e.name&&e.type!==i.type&&(e.name=e.name.replace(D,(t=T(t=e.type)?t.substr(6):"",".".concat(t="jpeg"===t?"jpg":t))))),this.result=e,a.success&&a.success.call(this,e)}},{key:"fail",value:function(e){var t=this.options;if(!t.error)throw e;t.error.call(this,e)}},{key:"abort",value:function(){this.aborted||(this.aborted=!0,this.reader?this.reader.abort():this.image.complete?this.fail(new Error("The compression process has been aborted.")):(this.image.onload=null,this.image.onabort()))}}])&&a(e.prototype,t),i&&a(e,i),Object.defineProperty(e,"prototype",{writable:!1}),r}()});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compressorjs",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "description": "JavaScript image compressor.",
5
5
  "main": "dist/compressor.common.js",
6
6
  "module": "dist/compressor.esm.js",
@@ -35,7 +35,7 @@
35
35
  "compress": "uglifyjs dist/compressor.js -o dist/compressor.min.js -c -m --comments /^!/",
36
36
  "dev": "rollup -c -m -w",
37
37
  "lint": "npm run lint:js && npm run lint:css",
38
- "lint:css": "stylelint {docs,examples}/**/*.{css,html} --fix",
38
+ "lint:css": "stylelint docs/**/*.css --fix",
39
39
  "lint:js": "eslint src test *.js --fix",
40
40
  "prepare": "husky install",
41
41
  "release": "npm run clean && npm run lint && npm run build && npm run compress && npm test",
@@ -48,40 +48,40 @@
48
48
  "is-blob": "^2.1.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@babel/core": "^7.15.5",
52
- "@babel/plugin-transform-object-assign": "^7.14.5",
53
- "@babel/preset-env": "^7.15.6",
54
- "@commitlint/cli": "^13.2.0",
55
- "@commitlint/config-conventional": "^13.2.0",
56
- "@rollup/plugin-babel": "^5.3.0",
57
- "@rollup/plugin-commonjs": "^21.0.0",
58
- "@rollup/plugin-node-resolve": "^13.0.5",
59
- "@rollup/plugin-replace": "^3.0.0",
60
- "babel-plugin-istanbul": "^6.0.0",
61
- "chai": "^4.3.4",
51
+ "@babel/core": "^7.21.0",
52
+ "@babel/plugin-transform-object-assign": "^7.18.6",
53
+ "@babel/preset-env": "^7.20.2",
54
+ "@commitlint/cli": "^17.4.4",
55
+ "@commitlint/config-conventional": "^17.4.4",
56
+ "@rollup/plugin-babel": "^5.3.1",
57
+ "@rollup/plugin-commonjs": "^21.1.0",
58
+ "@rollup/plugin-node-resolve": "^13.3.0",
59
+ "@rollup/plugin-replace": "^3.1.0",
60
+ "babel-plugin-istanbul": "^6.1.1",
61
+ "chai": "^4.3.7",
62
62
  "change-case": "^4.1.2",
63
63
  "codecov": "^3.8.3",
64
64
  "create-banner": "^2.0.0",
65
65
  "cross-env": "^7.0.3",
66
- "del-cli": "^4.0.1",
67
- "eslint": "^7.32.0",
68
- "eslint-config-airbnb-base": "^14.2.1",
69
- "eslint-plugin-import": "^2.24.2",
70
- "husky": "^7.0.2",
71
- "karma": "^6.3.4",
66
+ "del-cli": "^5.0.0",
67
+ "eslint": "^8.35.0",
68
+ "eslint-config-airbnb-base": "^15.0.0",
69
+ "eslint-plugin-import": "^2.27.5",
70
+ "husky": "^8.0.3",
71
+ "karma": "^6.4.1",
72
72
  "karma-chai": "^0.1.0",
73
- "karma-chrome-launcher": "^3.1.0",
73
+ "karma-chrome-launcher": "^3.1.1",
74
74
  "karma-coverage-istanbul-reporter": "^3.0.3",
75
75
  "karma-mocha": "^2.0.1",
76
76
  "karma-mocha-reporter": "^2.2.5",
77
- "karma-rollup-preprocessor": "^7.0.7",
78
- "lint-staged": "^11.2.0",
79
- "mocha": "^9.1.2",
80
- "puppeteer": "^10.4.0",
81
- "rollup": "^2.58.0",
82
- "stylelint": "^13.13.1",
83
- "stylelint-config-standard": "^22.0.0",
84
- "stylelint-order": "^4.1.0",
85
- "uglify-js": "^3.14.2"
77
+ "karma-rollup-preprocessor": "^7.0.8",
78
+ "lint-staged": "^13.1.2",
79
+ "mocha": "^10.2.0",
80
+ "puppeteer": "^19.7.2",
81
+ "rollup": "^2.79.1",
82
+ "stylelint": "^15.2.0",
83
+ "stylelint-config-standard": "^30.0.1",
84
+ "stylelint-order": "^6.0.2",
85
+ "uglify-js": "^3.17.4"
86
86
  }
87
87
  }
package/src/defaults.js CHANGED
@@ -13,6 +13,12 @@ export default {
13
13
  */
14
14
  checkOrientation: true,
15
15
 
16
+ /**
17
+ * Indicates if retain the image's Exif information after compressed.
18
+ * @type {boolean}
19
+ */
20
+ retainExif: false,
21
+
16
22
  /**
17
23
  * The max width of the output image.
18
24
  * @type {number}
package/src/index.js CHANGED
@@ -13,6 +13,8 @@ import {
13
13
  normalizeDecimalNumber,
14
14
  parseOrientation,
15
15
  resetAndGetOrientation,
16
+ getExif,
17
+ insertExif,
16
18
  } from './utilities';
17
19
 
18
20
  const { ArrayBuffer, FileReader } = WINDOW;
@@ -32,6 +34,7 @@ export default class Compressor {
32
34
  */
33
35
  constructor(file, options) {
34
36
  this.file = file;
37
+ this.exif = [];
35
38
  this.image = new Image();
36
39
  this.options = {
37
40
  ...DEFAULTS,
@@ -64,33 +67,48 @@ export default class Compressor {
64
67
 
65
68
  if (!ArrayBuffer) {
66
69
  options.checkOrientation = false;
70
+ options.retainExif = false;
67
71
  }
68
72
 
69
- if (URL && !options.checkOrientation) {
73
+ const isJPEGImage = mimeType === 'image/jpeg';
74
+ const checkOrientation = isJPEGImage && options.checkOrientation;
75
+ const retainExif = isJPEGImage && options.retainExif;
76
+
77
+ if (URL && !checkOrientation && !retainExif) {
70
78
  this.load({
71
79
  url: URL.createObjectURL(file),
72
80
  });
73
81
  } else {
74
82
  const reader = new FileReader();
75
- const checkOrientation = options.checkOrientation && mimeType === 'image/jpeg';
76
83
 
77
84
  this.reader = reader;
78
85
  reader.onload = ({ target }) => {
79
86
  const { result } = target;
80
87
  const data = {};
88
+ let orientation = 1;
81
89
 
82
90
  if (checkOrientation) {
83
91
  // Reset the orientation value to its default value 1
84
92
  // as some iOS browsers will render image with its orientation
85
- const orientation = resetAndGetOrientation(result);
93
+ orientation = resetAndGetOrientation(result);
86
94
 
87
- if (orientation > 1 || !URL) {
88
- // Generate a new URL which has the default orientation value
89
- data.url = arrayBufferToDataURL(result, mimeType);
95
+ if (orientation > 1) {
96
+ Object.assign(data, parseOrientation(orientation));
97
+ }
98
+ }
90
99
 
91
- if (orientation > 1) {
92
- Object.assign(data, parseOrientation(orientation));
93
- }
100
+ if (retainExif) {
101
+ this.exif = getExif(result);
102
+ }
103
+
104
+ if (checkOrientation || retainExif) {
105
+ if (
106
+ !URL
107
+
108
+ // Generate a new URL with the default orientation value 1.
109
+ || orientation > 1
110
+ ) {
111
+ data.url = arrayBufferToDataURL(result, mimeType);
94
112
  } else {
95
113
  data.url = URL.createObjectURL(file);
96
114
  }
@@ -110,7 +128,7 @@ export default class Compressor {
110
128
  this.reader = null;
111
129
  };
112
130
 
113
- if (checkOrientation) {
131
+ if (checkOrientation || retainExif) {
114
132
  reader.readAsArrayBuffer(file);
115
133
  } else {
116
134
  reader.readAsDataURL(file);
@@ -249,7 +267,9 @@ export default class Compressor {
249
267
  options.mimeType = 'image/jpeg';
250
268
  }
251
269
 
252
- if (options.mimeType === 'image/jpeg') {
270
+ const isJPEGImage = options.mimeType === 'image/jpeg';
271
+
272
+ if (isJPEGImage) {
253
273
  fillStyle = '#fff';
254
274
  }
255
275
 
@@ -280,20 +300,52 @@ export default class Compressor {
280
300
  return;
281
301
  }
282
302
 
283
- const done = (result) => {
303
+ const callback = (blob) => {
284
304
  if (!this.aborted) {
285
- this.done({
305
+ const done = (result) => this.done({
286
306
  naturalWidth,
287
307
  naturalHeight,
288
308
  result,
289
309
  });
310
+
311
+ if (blob && isJPEGImage && options.retainExif && this.exif && this.exif.length > 0) {
312
+ const next = (arrayBuffer) => done(toBlob(arrayBufferToDataURL(
313
+ insertExif(arrayBuffer, this.exif),
314
+ options.mimeType,
315
+ )));
316
+
317
+ if (blob.arrayBuffer) {
318
+ blob.arrayBuffer().then(next).catch(() => {
319
+ this.fail(new Error('Failed to read the compressed image with Blob.arrayBuffer().'));
320
+ });
321
+ } else {
322
+ const reader = new FileReader();
323
+
324
+ this.reader = reader;
325
+ reader.onload = ({ target }) => {
326
+ next(target.result);
327
+ };
328
+ reader.onabort = () => {
329
+ this.fail(new Error('Aborted to read the compressed image with FileReader.'));
330
+ };
331
+ reader.onerror = () => {
332
+ this.fail(new Error('Failed to read the compressed image with FileReader.'));
333
+ };
334
+ reader.onloadend = () => {
335
+ this.reader = null;
336
+ };
337
+ reader.readAsArrayBuffer(blob);
338
+ }
339
+ } else {
340
+ done(blob);
341
+ }
290
342
  }
291
343
  };
292
344
 
293
345
  if (canvas.toBlob) {
294
- canvas.toBlob(done, options.mimeType, options.quality);
346
+ canvas.toBlob(callback, options.mimeType, options.quality);
295
347
  } else {
296
- done(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
348
+ callback(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
297
349
  }
298
350
  }
299
351
 
@@ -304,20 +356,26 @@ export default class Compressor {
304
356
  }) {
305
357
  const { file, image, options } = this;
306
358
 
307
- if (URL && !options.checkOrientation) {
359
+ if (URL && image.src.indexOf('blob:') === 0) {
308
360
  URL.revokeObjectURL(image.src);
309
361
  }
310
362
 
311
363
  if (result) {
312
364
  // Returns original file if the result is greater than it and without size related options
313
- if (options.strict && result.size > file.size && options.mimeType === file.type && !(
314
- options.width > naturalWidth
315
- || options.height > naturalHeight
316
- || options.minWidth > naturalWidth
317
- || options.minHeight > naturalHeight
318
- || options.maxWidth < naturalWidth
319
- || options.maxHeight < naturalHeight
320
- )) {
365
+ if (
366
+ options.strict
367
+ && !options.retainExif
368
+ && result.size > file.size
369
+ && options.mimeType === file.type
370
+ && !(
371
+ options.width > naturalWidth
372
+ || options.height > naturalHeight
373
+ || options.minWidth > naturalWidth
374
+ || options.minHeight > naturalHeight
375
+ || options.maxWidth < naturalWidth
376
+ || options.maxHeight < naturalHeight
377
+ )
378
+ ) {
321
379
  result = file;
322
380
  } else {
323
381
  const date = new Date();
package/src/utilities.js CHANGED
@@ -279,3 +279,64 @@ export function getAdjustedSizes(
279
279
  height,
280
280
  };
281
281
  }
282
+
283
+ /**
284
+ * Get Exif information from the given array buffer.
285
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
286
+ * @returns {Array} The read Exif information.
287
+ */
288
+ export function getExif(arrayBuffer) {
289
+ const array = toArray(new Uint8Array(arrayBuffer));
290
+ const { length } = array;
291
+ const segments = [];
292
+ let start = 0;
293
+
294
+ while (start + 3 < length) {
295
+ const value = array[start];
296
+ const next = array[start + 1];
297
+
298
+ // SOS (Start of Scan)
299
+ if (value === 0xFF && next === 0xDA) {
300
+ break;
301
+ }
302
+
303
+ // SOI (Start of Image)
304
+ if (value === 0xFF && next === 0xD8) {
305
+ start += 2;
306
+ } else {
307
+ const offset = array[start + 2] * 256 + array[start + 3];
308
+ const end = start + offset + 2;
309
+ const segment = array.slice(start, end);
310
+
311
+ segments.push(segment);
312
+ start = end;
313
+ }
314
+ }
315
+
316
+ return segments.reduce((exifArray, current) => {
317
+ if (current[0] === 0xFF && current[1] === 0xE1) {
318
+ return exifArray.concat(current);
319
+ }
320
+
321
+ return exifArray;
322
+ }, []);
323
+ }
324
+
325
+ /**
326
+ * Insert Exif information into the given array buffer.
327
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
328
+ * @param {Array} exifArray - The Exif information to insert.
329
+ * @returns {ArrayBuffer} The transformed array buffer.
330
+ */
331
+ export function insertExif(arrayBuffer, exifArray) {
332
+ const array = toArray(new Uint8Array(arrayBuffer));
333
+
334
+ if (array[2] !== 0xFF || array[3] !== 0xE0) {
335
+ return arrayBuffer;
336
+ }
337
+
338
+ const app0Length = array[4] * 256 + array[5];
339
+ const newArrayBuffer = [0xFF, 0xD8].concat(exifArray, array.slice(4 + app0Length));
340
+
341
+ return new Uint8Array(newArrayBuffer);
342
+ }
package/types/index.d.ts CHANGED
@@ -2,6 +2,7 @@ declare namespace Compressor {
2
2
  export interface Options {
3
3
  strict?: boolean;
4
4
  checkOrientation?: boolean;
5
+ retainExif?: boolean;
5
6
  maxWidth?: number;
6
7
  maxHeight?: number;
7
8
  minWidth?: number;
package/CHANGELOG.md DELETED
@@ -1,48 +0,0 @@
1
- # Changelog
2
-
3
- ## 1.1.1 (Oct 5, 2021)
4
-
5
- - Fix loading error in Node.js (#137).
6
-
7
- ## 1.1.0 (Oct 1, 2021)
8
-
9
- - Add 2 new options: `convertTypes` (#123) and `resize` (#130).
10
- - Ignore the `strict` option when the `maxWidth/Height` option is set and its value is less than the natural width/height of the image (#134).
11
- .
12
-
13
- ## 1.0.7 (Nov 28, 2020)
14
-
15
- - Update the built-in dependencies for better adaptability.
16
-
17
- ## 1.0.6 (Nov 23, 2019)
18
-
19
- - Fix the `The operation is insecure` error (#57).
20
-
21
- ## 1.0.5 (Jan 23, 2019)
22
-
23
- - Fix the wrong generated URL when the given image's orientation is 1 (#64).
24
-
25
- ## 1.0.4 (Jan 19, 2019)
26
-
27
- - Regenerate the initial URL only when the orientation was reset for better performance (#63).
28
-
29
- ## 1.0.3 (Dec 18, 2018)
30
-
31
- - Convert `TypedArray` to `Array` manually instead of using Babel helpers for better browser compatibility (#60).
32
-
33
- ## 1.0.2 (Dec 10, 2018)
34
-
35
- - Upgrade `is-blob` to v2.
36
- - Move `examples` folder to `docs` folder.
37
-
38
- ## 1.0.1 (Oct 24, 2018)
39
-
40
- - Simplify the state of canvas for the `beforeDraw` option.
41
- - Ignore range error when the image does not have correct Exif information.
42
-
43
- ## 1.0.0 (Oct 15, 2018)
44
-
45
- - Supports 15 options: `beforeDraw`, `checkOrientation`, `convertSize`, `drew`, `error`, `height`, `maxHeight`, `maxWidth`, `mimeType`, `minHeight`, `minWidth`, `quality`, `strict`, `success` and `width`.
46
- - Support 1 method: `abort`.
47
- - Support to compress images of `File` or `Blob` object.
48
- - Supports to translate Exif Orientation information.