UNPKG

@awesome-compressor/browser-compress-image

Version:

🚀 A powerful, lightweight browser image compression library with TypeScript support. Compress JPEG, PNG, GIF images with multiple output formats (Blob, File, Base64, ArrayBuffer) and zero dependencies.

1 lines • 9.27 kB
import{__esmMin as e}from"./chunk-BFNP_Rck.js";import{init_logger as t,logger_default as n}from"./logger-C7b05YKe.js";import{LRUCache as r,init_lruCache as i}from"./lruCache-B8iebN31.js";async function a(e,t,n){switch(t){case`blob`:return e;case`file`:return new File([e],n||`compressed`,{type:e.type});case`base64`:return new Promise(t=>{let n=new FileReader;n.onloadend=()=>t(n.result),n.readAsDataURL(e)});case`arrayBuffer`:return e.arrayBuffer();default:throw Error(`Unsupported type: ${t}`)}}var o=e(()=>{});async function s(e,t,n){return!t&&!n?e():await new Promise((r,i)=>{let a=!1;e().then(e=>{a||(a=!0,r(e))}).catch(e=>{a||(a=!0,i(e))});let o;typeof n==`number`&&n>0&&(o=window.setTimeout(()=>{a||(a=!0,i(Error(`Compression timed out`)))},n));let s=()=>{a||(a=!0,i(Error(`Compression aborted`)))};t&&(t.aborted?s():t.addEventListener(`abort`,s,{once:!0}));let c=()=>{o!==void 0&&clearTimeout(o),t&&t.removeEventListener(`abort`,s)};(async()=>{try{let t=await e();a||(a=!0,r(t))}catch(e){a||(a=!0,i(e))}finally{c()}})()})}var c=e(()=>{});o(),i(),t(),c();async function l(e){switch(e){case`browser-image-compression`:{let{default:e}=await import(`./compressWithBrowserImageCompression-CmlhwJ5k.js`);return e}case`compressorjs`:{let{default:e}=await import(`./compressWithCompressorJS-aSeMvDqQ.js`);return e}case`gifsicle`:{let{default:e}=await import(`./compressWithGifsicle-CS7mAPWb.js`);return e}case`canvas`:{let{default:e}=await import(`./compressWithCanvas-0hixGPN5.js`);return e}case`jsquash`:{let{default:e}=await import(`./compressWithJsquash-WpUIwuyx.js`);return e}case`tinypng`:{let{compressWithTinyPng:e}=await import(`./compressWithTinyPng-D_KxnHYN.js`);return e}default:throw Error(`Unknown compression tool: ${e}`)}}const u=new r(100),d=[`browser-image-compression`,`compressorjs`];function f(e,t){return t.find(t=>t.name===e)}const p={png:[`jsquash`,`browser-image-compression`,`canvas`],gif:[`gifsicle`],webp:[`canvas`,`browser-image-compression`],jpeg:[`jsquash`,`compressorjs`,`canvas`,`browser-image-compression`],others:[`jsquash`,`browser-image-compression`,`canvas`]};async function m(e,t,r){let i;i=typeof t==`object`?t:{quality:t||.6,mode:`keepSize`,type:r||`blob`};let{quality:o=.6,mode:s=`keepSize`,targetWidth:c,targetHeight:l,maxWidth:d,maxHeight:f,preserveExif:m=!1,returnAllResults:_=!1,type:v=`blob`,toolConfigs:y=[],signal:b,timeoutMs:x}=i,S={quality:o,mode:s,targetWidth:c,targetHeight:l,maxWidth:d,maxHeight:f,preserveExif:m,toolConfigs:y,signal:b,timeoutMs:x},C=`${e.name}:${e.size}:type=${e.type}:q=${o}:m=${s}:tw=${c||``}:th=${l||``}:mw=${d||``}:mh=${f||``}:preserveExif=${m}:cfg=${JSON.stringify(y)}`;if(!_){let t=u.get(C);if(t)return n.debug(`Cache hit for`,C),a(t,v,e.name)}let w=e.type.includes(`png`)?p.png:e.type.includes(`gif`)?p.gif:e.type.includes(`webp`)?p.webp:e.type.includes(`jpeg`)||e.type.includes(`jpg`)?p.jpeg:p.others,T=y.some(e=>e.name===`tinypng`);if(T&&[`png`,`webp`,`jpeg`,`jpg`].some(t=>e.type.includes(t))&&(w=[...w,`tinypng`]),_)return await g(e,S,w,v);let E=await h(e,S,w);try{u.set(C,E)}catch(e){n.warn(`Failed to cache compress result`,e)}return a(E,v,e.name)}async function h(e,t,r){let i=performance.now();if(t.preserveExif){if(r=r.filter(e=>d.includes(e)),r.length===0)throw Error(`No EXIF-supporting tools available for this file type. Please disable preserveExif or use a different file format.`);n.log(`preserveExif=true, filtered tools:`,r)}let a=[],o=new AbortController,c=o.signal;if(t.signal){let e=t.signal;e.aborted?o.abort():e.addEventListener(`abort`,()=>o.abort(),{once:!0})}let u=r.map(async n=>{let r=performance.now();try{let i,a=f(n,t.toolConfigs||[]),o={quality:t.quality,mode:t.mode,targetWidth:t.targetWidth,targetHeight:t.targetHeight,maxWidth:t.maxWidth,maxHeight:t.maxHeight,preserveExif:t.preserveExif,...a},u=await l(n);o.signal=c,i=await s(()=>u(e,o),c,t.timeoutMs);let d=performance.now(),p=Math.round(d-r);return{tool:n,blob:i,size:i.size,success:!0,duration:p}}catch(t){try{o.abort()}catch{}let i=performance.now(),a=Math.round(i-r);return{tool:n,blob:e,size:e.size,success:!1,error:t instanceof Error?t.message:String(t),duration:a}}}),p=await Promise.allSettled(u);p.forEach(e=>{e.status===`fulfilled`?a.push(e.value):n.warn(`Compression tool failed:`,e.reason)});let m=a.filter(e=>e.success);if(m.length===0)return n.warn(`All compression attempts failed, returning original file`),e;let h=m.reduce((e,t)=>t.size<e.size?t:e);if(h.size>=e.size*.98&&t.quality>.85){let t=performance.now(),r=Math.round(t-i);return n.log(`Best compression (${h.tool}) size: ${h.size}, original: ${e.size}, using original (total: ${r}ms)`),e}let g=performance.now(),_=Math.round(g-i);return n.log(`Best compression result: ${h.tool} (${h.size} bytes, ${((e.size-h.size)/e.size*100).toFixed(1)}% reduction, ${h.duration}ms) - Total time: ${_}ms`),m.length>1&&n.table(m.map(t=>({Tool:t.tool,"Size (bytes)":t.size,"Reduction (%)":`${((e.size-t.size)/e.size*100).toFixed(1)}%`,"Duration (ms)":t.duration,"Speed (MB/s)":`${(e.size/1024/1024/(t.duration/1e3)).toFixed(2)}`}))),h.blob}async function g(e,t,r,i){let o=performance.now();if(t.preserveExif){if(r=r.filter(e=>d.includes(e)),r.length===0)throw Error(`No EXIF-supporting tools available for this file type. Please disable preserveExif or use a different file format.`);n.log(`preserveExif=true, filtered tools:`,r)}let c=[],u=r.map(async n=>{let r=performance.now();try{let i,a=f(n,t.toolConfigs||[]),o={quality:t.quality,mode:t.mode,targetWidth:t.targetWidth,targetHeight:t.targetHeight,maxWidth:t.maxWidth,maxHeight:t.maxHeight,preserveExif:t.preserveExif,...a},c=await l(n);i=await s(()=>c(e,o),t.signal,t.timeoutMs);let u=performance.now(),d=Math.round(u-r);return{tool:n,blob:i,size:i.size,success:!0,duration:d}}catch(t){let i=performance.now(),a=Math.round(i-r);return{tool:n,blob:e,size:e.size,success:!1,error:t instanceof Error?t.message:String(t),duration:a}}}),p=await Promise.allSettled(u);if(p.forEach(e=>{e.status===`fulfilled`?c.push(e.value):n.warn(`Compression tool failed:`,e.reason)}),c.length===0)throw Error(`All compression attempts failed`);let m=performance.now(),h=Math.round(m-o),g=await Promise.all(c.map(async t=>{let n=await a(t.blob,i,e.name);return{tool:t.tool,result:n,originalSize:e.size,compressedSize:t.size,compressionRatio:(e.size-t.size)/e.size*100,duration:t.duration,success:t.success,error:t.error}})),_=c.filter(e=>e.success),v;_.length>0?(v=_.reduce((e,t)=>t.size<e.size?t:e),v.size>=e.size*.98&&t.quality>.85&&(v={tool:`original`,blob:e,size:e.size,success:!0,duration:0})):v={tool:`original`,blob:e,size:e.size,success:!0,duration:0};let y=await a(v.blob,i,e.name);return n.log(`Best compression result: ${v.tool} (${v.size} bytes, ${((e.size-v.size)/e.size*100).toFixed(1)}% reduction) - Total time: ${h}ms`),_.length>1&&n.table(_.map(t=>({Tool:t.tool,"Size (bytes)":t.size,"Reduction (%)":`${((e.size-t.size)/e.size*100).toFixed(1)}%`,"Duration (ms)":t.duration,"Speed (MB/s)":`${(e.size/1024/1024/(t.duration/1e3)).toFixed(2)}`}))),{bestResult:y,bestTool:v.tool,allResults:g,totalDuration:h}}async function _(e,t){return await v(e,{quality:typeof t==`object`?t.quality||.6:t||.6,mode:typeof t==`object`&&t.mode||`keepSize`,targetWidth:typeof t==`object`?t.targetWidth:void 0,targetHeight:typeof t==`object`?t.targetHeight:void 0,maxWidth:typeof t==`object`?t.maxWidth:void 0,maxHeight:typeof t==`object`?t.maxHeight:void 0,preserveExif:typeof t==`object`&&t.preserveExif||!1,toolConfigs:typeof t==`object`&&t.toolConfigs||[]})}async function v(e,t){let r=performance.now(),i=e.type.includes(`png`)?p.png:e.type.includes(`gif`)?p.gif:e.type.includes(`webp`)?p.webp:p.others,a=t.toolConfigs?.some(e=>e.name===`tinypng`);if(a&&[`png`,`webp`,`jpeg`,`jpg`].some(t=>e.type.includes(t))&&(i=[...i,`tinypng`]),t.preserveExif){if(i=i.filter(e=>d.includes(e)),i.length===0)throw Error(`No EXIF-supporting tools available for this file type. Please disable preserveExif or use a different file format.`);n.log(`preserveExif=true, filtered tools:`,i)}let o=[],c=i.map(async n=>{let r=performance.now();try{let i,a=f(n,t.toolConfigs||[]),o={quality:t.quality,mode:t.mode,targetWidth:t.targetWidth,targetHeight:t.targetHeight,maxWidth:t.maxWidth,maxHeight:t.maxHeight,preserveExif:t.preserveExif,...a},c=await l(n);i=await s(()=>c(e,o),t.signal,t.timeoutMs);let u=performance.now(),d=Math.round(u-r);return{tool:n,blob:i,size:i.size,success:!0,duration:d}}catch(t){let i=performance.now(),a=Math.round(i-r);return{tool:n,blob:e,size:e.size,success:!1,error:t instanceof Error?t.message:String(t),duration:a}}}),u=await Promise.allSettled(c);u.forEach(e=>{e.status===`fulfilled`&&o.push(e.value)});let m=o.filter(e=>e.success),h=m.length>0?m.reduce((e,t)=>t.size<e.size?t:e):{tool:`none`,blob:e,size:e.size,success:!1,duration:0},g=performance.now(),_=Math.round(g-r);return{bestTool:h.tool,compressedFile:h.blob,originalSize:e.size,compressedSize:h.size,compressionRatio:(e.size-h.size)/e.size*100,totalDuration:_,toolsUsed:o.map(t=>({tool:t.tool,size:t.size,duration:t.duration,compressionRatio:(e.size-t.size)/e.size*100,success:t.success,error:t.error}))}}export{m as compress,_ as compressWithStats,a as convertBlobToType,c as init_abort,o as init_convertBlobToType,s as runWithAbortAndTimeout};