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
package/dist/compressor.min.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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
|
-
!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 s(){return(s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var i,r=arguments[t];for(i in r)Object.prototype.hasOwnProperty.call(r,i)&&(e[i]=r[i])}return e}).apply(this,arguments)}var e,t,a,l,h,c,d,o,i={exports:{}},L=(e=i,"undefined"!=typeof window&&(a=(t=window).HTMLCanvasElement&&t.HTMLCanvasElement.prototype,l=t.Blob&&function(){try{return Boolean(new Blob)}catch(e){return!1}}(),h=l&&t.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(e){return!1}}(),c=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder,d=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,o=(l||c)&&t.atob&&t.ArrayBuffer&&t.Uint8Array&&function(e){var t,i,r,a,o,n=e.match(d);if(!n)throw new Error("invalid data URI");for(t=n[2]?n[1]:"text/plain"+(n[3]||";charset=US-ASCII"),o=!!n[4],e=e.slice(n[0].length),i=(o?atob:decodeURIComponent)(e),n=new ArrayBuffer(i.length),r=new Uint8Array(n),a=0;a<i.length;a+=1)r[a]=i.charCodeAt(a);return l?new Blob([h?r:n],{type:t}):((o=new c).append(n),o.getBlob(t))},t.HTMLCanvasElement&&!a.toBlob&&(a.mozGetAsFile?a.toBlob=function(e,t,i){var r=this;setTimeout(function(){i&&a.toDataURL&&o?e(o(r.toDataURL(t,i))):e(r.mozGetAsFile("blob",t))})}:a.toDataURL&&o&&(a.msToBlob?a.toBlob=function(e,t,i){var r=this;setTimeout(function(){(t&&"image/png"!==t||i)&&a.toDataURL&&o?e(o(r.toDataURL(t,i))):e(r.msToBlob(t))})}:a.toBlob=function(e,t,i){var r=this;setTimeout(function(){e(o(r.toDataURL(t,i)))})})),e.exports?e.exports=o:t.dataURLtoBlob=o),i.exports),r={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 n="undefined"!=typeof window&&void 0!==window.document?window:{},j=e=>0<e&&e<1/0,f=Array.prototype["slice"];function D(e){return Array.from?Array.from(e):f.call(e)}const u=/^image\/.+$/;function k(e){return u.test(e)}const m=String["fromCharCode"];const g=n["btoa"];function z(e,t){var i=[];let r=new Uint8Array(e);for(;0<r.length;)i.push(m.apply(null,D(r.subarray(0,8192)))),r=r.subarray(8192);return`data:${t};base64,`+g(i.join(""))}function b(e){var a,o,n,s,l=new DataView(e);let h;try{let t,i,r;if(255===l.getUint8(0)&&216===l.getUint8(1)){var c=l.byteLength;let e=2;for(;e+1<c;){if(255===l.getUint8(e)&&225===l.getUint8(e+1)){i=e;break}e+=1}}if(r=i&&(a=i+4,o=i+10,"Exif"===function(e,t,i){let r="",a;for(i+=t,a=t;a<i;a+=1)r+=m(e.getUint8(a));return r}(l,a,4))&&(n=l.getUint16(o),(t=18761===n)||19789===n)&&42===l.getUint16(o+2,t)&&8<=(s=l.getUint32(o+4,t))?o+s:r){var d,f=l.getUint16(r,t);let e;for(e=0;e<f;e+=1)if(d=r+12*e+2,274===l.getUint16(d,t)){d+=8,h=l.getUint16(d,t),l.setUint16(d,1,t);break}}}catch(e){h=1}return h}const p=/\.\d*(?:0|9){12}\d*$/;function H(e,t){t=1<arguments.length&&void 0!==t?t:1e11;return p.test(e)?Math.round(e*t)/t:e}function O(e,t){let{aspectRatio:i,height:r,width:a}=e;var o,e=1<arguments.length&&void 0!==t?t:"none",t=j(a),n=j(r);return t&&n?(o=r*i,("contain"===e||"none"===e)&&o>a||"cover"===e&&o<a?r=a/i:a=r*i):t?r=a/i:n&&(a=r*i),{width:a,height:r}}const{ArrayBuffer:w,FileReader:C}=n,y=n.URL||n.webkitURL,v=/\.\w+$/,B=n.Compressor;return class U{constructor(e,t){this.file=e,this.exif=[],this.image=new Image,this.options={...r,...t},this.aborted=!1,this.result=null,this.init()}init(){const{file:r,options:e}=this;if(t=r,"undefined"!=typeof Blob&&(t instanceof Blob||"[object Blob]"===Object.prototype.toString.call(t))){const a=r.type;if(k(a))if(y&&C){w||(e.checkOrientation=!1,e.retainExif=!1);var t="image/jpeg"===a;const o=t&&e.checkOrientation,n=t&&e.retainExif;!y||o||n?(t=new C,(this.reader=t).onload=e=>{var e=(e=e.target).result,t={};let i=1;o&&1<(i=b(e))&&s(t,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}}(i)),n&&(this.exif=function(e){var t=D(new Uint8Array(e)),i=t.length,r=[];let a=0;for(;a+3<i;){var o=t[a],n=t[a+1];if(255===o&&218===n)break;255===o&&216===n?a+=2:(o=256*t[a+2]+t[a+3],n=a+o+2,o=t.slice(a,n),r.push(o),a=n)}return r.reduce((e,t)=>255===t[0]&&225===t[1]?e.concat(t):e,[])}(e)),o||n?!y||1<i?t.url=z(e,a):t.url=y.createObjectURL(r):t.url=e,this.load(t)},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},o||n?t.readAsArrayBuffer(r):t.readAsDataURL(r)):this.load({url:y.createObjectURL(r)})}else this.fail(new Error("The current browser does not support image compression."));else this.fail(new Error("The first argument must be an image File or Blob object."))}else this.fail(new Error("The first argument must be a File or Blob object."))}load(e){const{file:t,image:i}=this;i.onload=()=>{this.draw({...e,naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight})},i.onabort=()=>{this.fail(new Error("Aborted to load the image."))},i.onerror=()=>{this.fail(new Error("Failed to load the image."))},n.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(n.navigator.userAgent)&&(i.crossOrigin="anonymous"),i.alt=t.name,i.src=e.url}draw(e){let{naturalWidth:a,naturalHeight:o,rotate:t=0,scaleX:i=1,scaleY:r=1}=e;const{file:n,image:s,options:l}=this;var h=(e=document.createElement("canvas")).getContext("2d"),c=Math.abs(t)%180==90,d=("contain"===l.resize||"cover"===l.resize)&&j(l.width)&&j(l.height);let f=Math.max(l.maxWidth,0)||1/0,u=Math.max(l.maxHeight,0)||1/0,m=Math.max(l.minWidth,0)||0,g=Math.max(l.minHeight,0)||0,b=a/o,{width:p,height:w}=l;c&&([f,u]=[u,f],[m,g]=[g,m],[p,w]=[w,p]),d&&(b=p/w),{width:f,height:u}=O({aspectRatio:b,width:f,height:u},"contain"),{width:m,height:g}=O({aspectRatio:b,width:m,height:g},"cover"),d?{width:p,height:w}=O({aspectRatio:b,width:p,height:w},l.resize):{width:p=a,height:w=o}=O({aspectRatio:b,width:p,height:w}),p=Math.floor(H(Math.min(Math.max(p,m),f))),w=Math.floor(H(Math.min(Math.max(w,g),u)));var y,v,B,U=-p/2,x=-w/2,A=p,R=w,T=[];d&&(y=d=0,v=a,B=o,{width:v,height:B}=O({aspectRatio:b,width:a,height:o},{contain:"cover",cover:"contain"}[l.resize]),d=(a-v)/2,y=(o-B)/2,T.push(d,y,v,B)),T.push(U,x,A,R),c&&([p,w]=[w,p]),e.width=p,e.height=w,k(l.mimeType)||(l.mimeType=n.type);let E="transparent";n.size>l.convertSize&&0<=l.convertTypes.indexOf(l.mimeType)&&(l.mimeType="image/jpeg");const M="image/jpeg"===l.mimeType;M&&(E="#fff"),h.fillStyle=E,h.fillRect(0,0,p,w),l.beforeDraw&&l.beforeDraw.call(this,h,e),this.aborted||(h.save(),h.translate(p/2,w/2),h.rotate(t*Math.PI/180),h.scale(i,r),h.drawImage(s,...T),h.restore(),l.drew&&l.drew.call(this,h,e),this.aborted)||(d=e=>{if(!this.aborted){const r=e=>this.done({naturalWidth:a,naturalHeight:o,result:e});if(e&&M&&l.retainExif&&this.exif&&0<this.exif.length){const i=e=>{return r(L(z((t=this.exif,255!==(i=D(new Uint8Array(e)))[2]||224!==i[3]?e:(e=256*i[4]+i[5],t=[255,216].concat(t,i.slice(4+e)),new Uint8Array(t))),l.mimeType)));var t,i};var t;e.arrayBuffer?e.arrayBuffer().then(i).catch(()=>{this.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))}):(t=new C,(this.reader=t).onload=e=>{e=e.target,i(e.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(e))}else r(e)}},e.toBlob?e.toBlob(d,l.mimeType,l.quality):d(L(e.toDataURL(l.mimeType,l.quality))))}done(e){let{naturalWidth:t,naturalHeight:i,result:r}=e;var{file:e,image:a,options:o}=this;y&&0===a.src.indexOf("blob:")&&y.revokeObjectURL(a.src),!r||o.strict&&!o.retainExif&&r.size>e.size&&o.mimeType===e.type&&!(o.width>t||o.height>i||o.minWidth>t||o.minHeight>i||o.maxWidth<t||o.maxHeight<i)?r=e:(a=new Date,r.lastModified=a.getTime(),r.lastModifiedDate=a,r.name=e.name,r.name&&r.type!==e.type&&(r.name=r.name.replace(v,function(e){let t=k(e)?e.substr(6):"";return"."+(t="jpeg"===t?"jpg":t)}(r.type)))),this.result=r,o.success&&o.success.call(this,r)}fail(e){var t=this.options;if(!t.error)throw e;t.error.call(this,e)}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.onabort()))}static noConflict(){return window.Compressor=B,U}static setDefaults(e){s(r,e)}}});
|
|
10
|
+
((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(){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)!{}.hasOwnProperty.call(i,r)||(e[r]=i[r])}return e}).apply(null,arguments)}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 a=null!=arguments[e]?arguments[e]:{};e%2?t(Object(a),!0).forEach(function(e){var t,r;t=i,r=a[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(a)):t(Object(a)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(a,e))})}return i}function o(e){e=((e,t)=>{if("object"!=typeof e||!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:e+""}function x(e){return 0<e&&e<1/0}var e,r,l,c,h,u,f,d,i={exports:{}},O=(e=i,"undefined"!=typeof window&&(l=(r=window).HTMLCanvasElement&&r.HTMLCanvasElement.prototype,c=r.Blob&&(()=>{try{return Boolean(new Blob)}catch(e){return!1}})(),h=c&&r.Uint8Array&&(()=>{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,a,n,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"),n=!!o[4],e=e.slice(o[0].length),r=(n?atob:decodeURIComponent)(e),o=new ArrayBuffer(r.length),i=new Uint8Array(o),a=0;a<r.length;a+=1)i[a]=r.charCodeAt(a);return c?new Blob([h?i:o],{type:t}):((n=new u).append(o),n.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},g="undefined"!=typeof window&&void 0!==window.document?window:{},p=Array.prototype.slice;function j(e){return Array.from?Array.from(e):p.call(e)}var b=/^image\/.+$/;function T(e){return b.test(e)}var y=String.fromCharCode;var w=g.btoa;function A(e,t){for(var r=[],i=new Uint8Array(e);0<i.length;)r.push(y.apply(null,j(i.subarray(0,8192)))),i=i.subarray(8192);return"data:".concat(t,";base64,").concat(w(r.join("")))}function v(e){var t,r,i,a,n,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&&(a=r+10,"Exif"===((e,t,r)=>{var i,a="";for(r+=t,i=t;i<r;i+=1)a+=y(e.getUint8(i));return a})(s,r+4,4))&&((l=18761===(n=s.getUint16(a)))||19789===n)&&42===s.getUint16(a+2,l)&&8<=(o=s.getUint32(a+4,l))?a+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,a=e.height,e=e.width,t=1<arguments.length&&void 0!==t?t:"none",n=x(e),o=x(a);return n&&o?(r=a*i,("contain"===t||"none"===t)&&e<r||"cover"===t&&r<e?a=e/i:e=a*i):n?a=e/i:o&&(e=a*i),{width:e,height:a}}var U=g.ArrayBuffer,k=g.FileReader,D=g.URL||g.webkitURL,M=/\.\w+$/,L=g.Compressor;return(()=>{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()}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,a,n,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)?D&&k?(U||(t.checkOrientation=!1,t.retainExif=!1),a=(e="image/jpeg"===i)&&t.checkOrientation,n=e&&t.retainExif,!D||a||n?(e=new k,(this.reader=e).onload=function(e){var e=e.target.result,t={},r=1;a&&1<(r=v(e))&&s(t,(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)),n&&(o.exif=(e=>{for(var t=j(new Uint8Array(e)),r=t.length,i=[],a=0;a+3<r;){var n=t[a],o=t[a+1];if(255===n&&218===o)break;255===n&&216===o?a+=2:(n=a+(256*t[a+2]+t[a+3])+2,o=t.slice(a,n),i.push(o),a=n)}return i.reduce(function(e,t){return 255===t[0]&&225===t[1]?e.concat(t):e},[])})(e)),t.url=a||n?!D||1<r?A(e,i):D.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},a||n?e.readAsArrayBuffer(l):e.readAsDataURL(l)):this.load({url:D.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(){(()=>{try{var e,t,r,i=document.createElement("canvas"),a=(i.width=2,i.height=1,i.getContext("2d"));if(a)return(e=a.createImageData(2,1)).data[0]=12,e.data[1]=23,e.data[2]=34,e.data[3]=255,e.data[4]=45,e.data[5]=56,e.data[6]=67,e.data[7]=255,a.putImageData(e,0,0),t=a.getImageData(0,0,2,1),r=[12,23,34,255,45,56,67,255],t.data.every(function(e,t){return e===r[t]})}catch(e){}})()?t.draw(n(n({},e),{},{naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight})):t.done({naturalWidth:i.naturalWidth,naturalHeight:i.naturalHeight,result:null})},i.onabort=function(){t.fail(new Error("Aborted to load the image."))},i.onerror=function(){t.fail(new Error("Failed to load the image."))},g.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(g.navigator.userAgent)&&(i.crossOrigin="anonymous"),i.alt=r.name,i.src=e.url}},{key:"draw",value:function(e){var a=this,n=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)&&x(s.width)&&x(s.height),d=Math.max(s.maxWidth,0)||1/0,m=Math.max(s.maxHeight,0)||1/0,g=Math.max(s.minWidth,0)||0,p=Math.max(s.minHeight,0)||0,b=n/o,y=s.width,w=s.height,v=(u&&(d=(v=[m,d])[0],m=v[1],g=(v=[p,g])[0],p=v[1],y=(v=[w,y])[0],w=v[1]),E({aspectRatio:b=f?y/w:b,width:d,height:m},"contain")),v=(d=v.width,m=v.height,E({aspectRatio:b,width:g,height:p},"cover")),v=(g=v.width,p=v.height,w=f?(y=(v=E({aspectRatio:b,width:y,height:w},s.resize)).width,v.height):(y=void 0===(B=(v=E({aspectRatio:b,width:y,height:w})).width)?n:B,void 0===(B=v.height)?o:B),-(y=Math.floor(R(Math.min(Math.max(y,g),d))))/2),B=-(w=Math.floor(R(Math.min(Math.max(w,p),m))))/2,g=y,d=w,p=[],m=(f&&(0,m=(b=E({aspectRatio:b,width:m=n,height:f=o},{contain:"cover",cover:"contain"}[s.resize])).width,p.push((n-m)/2,(o-(f=b.height))/2,m,f)),p.push(v,B,g,d),u&&(y=(b=[w,y])[0],w=b[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;a.aborted||(i=function(e){return a.done({naturalWidth:n,naturalHeight:o,result:e})},e&&U&&s.retainExif&&a.exif&&0<a.exif.length?(t=function(e){return i(O(A((e=e,t=a.exif,255!==(r=j(new Uint8Array(e)))[2]||224!==r[3]?e:(e=[255,216].concat(t,r.slice(4+(256*r[4]+r[5]))),new Uint8Array(e))),s.mimeType)));var t,r},e.arrayBuffer?e.arrayBuffer().then(t).catch(function(){a.fail(new Error("Failed to read the compressed image with Blob.arrayBuffer()."))}):(r=new k,(a.reader=r).onload=function(e){e=e.target;t(e.result)},r.onabort=function(){a.fail(new Error("Aborted to read the compressed image with FileReader."))},r.onerror=function(){a.fail(new Error("Failed to read the compressed image with FileReader."))},r.onloadend=function(){a.reader=null},r.readAsArrayBuffer(e))):i(e))},c.toBlob?c.toBlob(f,s.mimeType,s.quality):f(O(c.toDataURL(s.mimeType,s.quality))))}},{key:"done",value:function(t){var e=t.naturalWidth,r=t.naturalHeight,t=t.result,i=this.file,a=this.image,n=this.options;if(D&&0===a.src.indexOf("blob:")&&D.revokeObjectURL(a.src),t)if(n.strict&&!n.retainExif&&t.size>i.size&&n.mimeType===i.type&&!(n.width>e||n.height>r||n.minWidth>e||n.minHeight>r||n.maxWidth<e||n.maxHeight<r))t=i;else{a=i.name;a&&t.type!==i.type&&(a=a.replace(M,(e=T(e=t.type)?e.substr(6):"",".".concat(e="jpeg"===e?"jpg":e))));try{t=new File([t],a,{type:t.type})}catch(e){r=new Date;t.name=a,t.lastModified=r.getTime(),t.lastModifiedDate=r}}else t=i;this.result=t,n.success&&n.success.call(this,t)}},{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}),e;var e,t,i})()});
|
package/package.json
CHANGED
|
@@ -1,34 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compressorjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "JavaScript image compressor.",
|
|
5
5
|
"main": "dist/compressor.common.js",
|
|
6
6
|
"module": "dist/compressor.esm.js",
|
|
7
7
|
"browser": "dist/compressor.js",
|
|
8
8
|
"types": "types/index.d.ts",
|
|
9
|
-
"repository": "fengyuanchen/compressorjs",
|
|
10
|
-
"homepage": "https://fengyuanchen.github.io/compressorjs",
|
|
11
|
-
"license": "MIT",
|
|
12
|
-
"author": {
|
|
13
|
-
"name": "Chen Fengyuan",
|
|
14
|
-
"url": "https://chenfengyuan.com/"
|
|
15
|
-
},
|
|
16
9
|
"files": [
|
|
17
10
|
"src",
|
|
18
11
|
"dist",
|
|
19
12
|
"types"
|
|
20
13
|
],
|
|
21
|
-
"keywords": [
|
|
22
|
-
"image",
|
|
23
|
-
"compress",
|
|
24
|
-
"compressor",
|
|
25
|
-
"compressor.js",
|
|
26
|
-
"image-compressor",
|
|
27
|
-
"lossy-compression",
|
|
28
|
-
"javascript",
|
|
29
|
-
"front-end",
|
|
30
|
-
"web"
|
|
31
|
-
],
|
|
32
14
|
"scripts": {
|
|
33
15
|
"build": "rollup -c",
|
|
34
16
|
"clean": "del-cli dist",
|
|
@@ -40,48 +22,71 @@
|
|
|
40
22
|
"prepare": "husky install",
|
|
41
23
|
"release": "npm run clean && npm run lint && npm run build && npm run compress && npm test",
|
|
42
24
|
"start": "npm run dev",
|
|
43
|
-
"test": "cross-env NODE_ENV=test karma start test/karma.conf.js"
|
|
44
|
-
|
|
25
|
+
"test": "cross-env NODE_ENV=test karma start test/karma.conf.js"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/fengyuanchen/compressorjs.git"
|
|
45
30
|
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"image",
|
|
33
|
+
"compress",
|
|
34
|
+
"compressor",
|
|
35
|
+
"compressor.js",
|
|
36
|
+
"image-compressor",
|
|
37
|
+
"lossy-compression",
|
|
38
|
+
"javascript",
|
|
39
|
+
"front-end",
|
|
40
|
+
"web"
|
|
41
|
+
],
|
|
42
|
+
"author": {
|
|
43
|
+
"name": "Chen Fengyuan",
|
|
44
|
+
"url": "https://chenfengyuan.com/"
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/fengyuanchen/compressorjs/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://fengyuanchen.github.io/compressorjs",
|
|
46
51
|
"dependencies": {
|
|
47
52
|
"blueimp-canvas-to-blob": "^3.29.0",
|
|
48
53
|
"is-blob": "^2.1.0"
|
|
49
54
|
},
|
|
50
55
|
"devDependencies": {
|
|
51
|
-
"@babel/core": "^7.
|
|
52
|
-
"@babel/plugin-transform-object-assign": "^7.
|
|
53
|
-
"@babel/preset-env": "^7.
|
|
54
|
-
"@commitlint/cli": "^17.
|
|
55
|
-
"@commitlint/config-conventional": "^17.
|
|
56
|
+
"@babel/core": "^7.29.0",
|
|
57
|
+
"@babel/plugin-transform-object-assign": "^7.27.1",
|
|
58
|
+
"@babel/preset-env": "^7.29.2",
|
|
59
|
+
"@commitlint/cli": "^17.8.1",
|
|
60
|
+
"@commitlint/config-conventional": "^17.8.1",
|
|
56
61
|
"@rollup/plugin-babel": "^5.3.1",
|
|
57
62
|
"@rollup/plugin-commonjs": "^21.1.0",
|
|
58
63
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
59
64
|
"@rollup/plugin-replace": "^3.1.0",
|
|
60
65
|
"babel-plugin-istanbul": "^6.1.1",
|
|
61
|
-
"chai": "^4.
|
|
66
|
+
"chai": "^4.5.0",
|
|
62
67
|
"change-case": "^4.1.2",
|
|
63
68
|
"codecov": "^3.8.3",
|
|
64
69
|
"create-banner": "^2.0.0",
|
|
65
70
|
"cross-env": "^7.0.3",
|
|
66
|
-
"del-cli": "^5.
|
|
67
|
-
"eslint": "^8.
|
|
71
|
+
"del-cli": "^5.1.0",
|
|
72
|
+
"eslint": "^8.57.1",
|
|
68
73
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
69
|
-
"eslint-plugin-import": "^2.
|
|
74
|
+
"eslint-plugin-import": "^2.32.0",
|
|
70
75
|
"husky": "^8.0.3",
|
|
71
|
-
"karma": "^6.4.
|
|
76
|
+
"karma": "^6.4.4",
|
|
72
77
|
"karma-chai": "^0.1.0",
|
|
73
|
-
"karma-chrome-launcher": "^3.
|
|
78
|
+
"karma-chrome-launcher": "^3.2.0",
|
|
74
79
|
"karma-coverage-istanbul-reporter": "^3.0.3",
|
|
75
80
|
"karma-mocha": "^2.0.1",
|
|
76
81
|
"karma-mocha-reporter": "^2.2.5",
|
|
77
82
|
"karma-rollup-preprocessor": "^7.0.8",
|
|
78
|
-
"lint-staged": "^13.
|
|
79
|
-
"mocha": "^10.2
|
|
80
|
-
"puppeteer": "^19.
|
|
81
|
-
"rollup": "^2.
|
|
82
|
-
"stylelint": "^15.
|
|
83
|
+
"lint-staged": "^13.3.0",
|
|
84
|
+
"mocha": "^10.8.2",
|
|
85
|
+
"puppeteer": "^19.11.1",
|
|
86
|
+
"rollup": "^2.80.0",
|
|
87
|
+
"stylelint": "^15.11.0",
|
|
83
88
|
"stylelint-config-standard": "^30.0.1",
|
|
84
|
-
"stylelint-order": "^6.0.
|
|
85
|
-
"uglify-js": "^3.
|
|
89
|
+
"stylelint-order": "^6.0.4",
|
|
90
|
+
"uglify-js": "^3.19.3"
|
|
86
91
|
}
|
|
87
92
|
}
|
package/src/index.js
CHANGED
|
@@ -7,14 +7,15 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
arrayBufferToDataURL,
|
|
9
9
|
getAdjustedSizes,
|
|
10
|
+
getExif,
|
|
10
11
|
imageTypeToExtension,
|
|
12
|
+
insertExif,
|
|
13
|
+
isCanvasAvailable,
|
|
11
14
|
isImageType,
|
|
12
15
|
isPositiveNumber,
|
|
13
16
|
normalizeDecimalNumber,
|
|
14
17
|
parseOrientation,
|
|
15
18
|
resetAndGetOrientation,
|
|
16
|
-
getExif,
|
|
17
|
-
insertExif,
|
|
18
19
|
} from './utilities';
|
|
19
20
|
|
|
20
21
|
const { ArrayBuffer, FileReader } = WINDOW;
|
|
@@ -140,11 +141,19 @@ export default class Compressor {
|
|
|
140
141
|
const { file, image } = this;
|
|
141
142
|
|
|
142
143
|
image.onload = () => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
if (isCanvasAvailable()) {
|
|
145
|
+
this.draw({
|
|
146
|
+
...data,
|
|
147
|
+
naturalWidth: image.naturalWidth,
|
|
148
|
+
naturalHeight: image.naturalHeight,
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
this.done({
|
|
152
|
+
naturalWidth: image.naturalWidth,
|
|
153
|
+
naturalHeight: image.naturalHeight,
|
|
154
|
+
result: null,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
148
157
|
};
|
|
149
158
|
image.onabort = () => {
|
|
150
159
|
this.fail(new Error('Aborted to load the image.'));
|
|
@@ -378,19 +387,31 @@ export default class Compressor {
|
|
|
378
387
|
) {
|
|
379
388
|
result = file;
|
|
380
389
|
} else {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
result.lastModified = date.getTime();
|
|
384
|
-
result.lastModifiedDate = date;
|
|
385
|
-
result.name = file.name;
|
|
390
|
+
let fileName = file.name;
|
|
386
391
|
|
|
387
392
|
// Convert the extension to match its type
|
|
388
|
-
if (
|
|
389
|
-
|
|
393
|
+
if (fileName && result.type !== file.type) {
|
|
394
|
+
fileName = fileName.replace(
|
|
390
395
|
REGEXP_EXTENSION,
|
|
391
396
|
imageTypeToExtension(result.type),
|
|
392
397
|
);
|
|
393
398
|
}
|
|
399
|
+
|
|
400
|
+
try {
|
|
401
|
+
// Convert the resulting Blob object into a File object for modern browsers.
|
|
402
|
+
result = new File([result], fileName, {
|
|
403
|
+
type: result.type,
|
|
404
|
+
});
|
|
405
|
+
} catch (error) {
|
|
406
|
+
// Fallback to Blob if the File constructor is not supported.
|
|
407
|
+
const date = new Date();
|
|
408
|
+
|
|
409
|
+
result.name = fileName;
|
|
410
|
+
|
|
411
|
+
// The last modified date is not accurate, but it's better than nothing.
|
|
412
|
+
result.lastModified = date.getTime();
|
|
413
|
+
result.lastModifiedDate = date;
|
|
414
|
+
}
|
|
394
415
|
}
|
|
395
416
|
} else {
|
|
396
417
|
// Returns original file if the result is null in some cases.
|
package/src/utilities.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
WINDOW,
|
|
3
|
-
} from './constants';
|
|
1
|
+
import { WINDOW } from './constants';
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Check if the given value is a positive number.
|
|
@@ -68,6 +66,52 @@ export function getStringFromCharCode(dataView, start, length) {
|
|
|
68
66
|
return str;
|
|
69
67
|
}
|
|
70
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Check if `canvas.getContext('2d').getImageData` is available,
|
|
71
|
+
* FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode (#137)
|
|
72
|
+
* @link https://github.com/nodeca/pica/blob/master/lib/utils.js
|
|
73
|
+
* @returns {boolean} Returns `true` if it is available, else `false`.
|
|
74
|
+
*/
|
|
75
|
+
export function isCanvasAvailable() {
|
|
76
|
+
try {
|
|
77
|
+
const canvas = document.createElement('canvas');
|
|
78
|
+
|
|
79
|
+
canvas.width = 2;
|
|
80
|
+
canvas.height = 1;
|
|
81
|
+
|
|
82
|
+
const context = canvas.getContext('2d');
|
|
83
|
+
|
|
84
|
+
if (!context) return false;
|
|
85
|
+
|
|
86
|
+
// Create 2x1 image data containing RGBA values for two pixels
|
|
87
|
+
const imageData = context.createImageData(2, 1);
|
|
88
|
+
|
|
89
|
+
// First pixel: R=12, G=23, B=34, A=255
|
|
90
|
+
imageData.data[0] = 12;
|
|
91
|
+
imageData.data[1] = 23;
|
|
92
|
+
imageData.data[2] = 34;
|
|
93
|
+
imageData.data[3] = 255;
|
|
94
|
+
|
|
95
|
+
// Second pixel: R=45, G=56, B=67, A=255
|
|
96
|
+
imageData.data[4] = 45;
|
|
97
|
+
imageData.data[5] = 56;
|
|
98
|
+
imageData.data[6] = 67;
|
|
99
|
+
imageData.data[7] = 255;
|
|
100
|
+
|
|
101
|
+
context.putImageData(imageData, 0, 0);
|
|
102
|
+
|
|
103
|
+
const readBack = context.getImageData(0, 0, 2, 1);
|
|
104
|
+
|
|
105
|
+
// Expected pixel data (matching the written values)
|
|
106
|
+
const expected = [12, 23, 34, 255, 45, 56, 67, 255];
|
|
107
|
+
|
|
108
|
+
// Compare element by element to ensure write and read consistency
|
|
109
|
+
return readBack.data.every((value, index) => value === expected[index]);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
71
115
|
const { btoa } = WINDOW;
|
|
72
116
|
|
|
73
117
|
/**
|