UNPKG

edgeit.js

Version:

基于Canvas的智能图片描边处理库

2 lines (1 loc) 2.17 kB
const t={strokeColor:"#000000",strokeWidth:2,cache:!0,willReadFrequently:!0,imageSmoothing:!0};class e{static#t=new Map;constructor(e={}){this.config={...t,...e}}async process(t){try{const e=await this.#e(t),{naturalWidth:a,naturalHeight:n}=e,i=this.#a(a,n),{canvas:s,context:o}=this.#n(i.width,i.height);this.#i(o,e,i);const r=o.getImageData(0,0,i.width,i.height),h=this.#s(r),c=this.#o(e,h,i);return this.#r(c)}catch(t){throw t}}#a(t,e){const{width:a,height:n}=this.config,i=t/e;return{width:a||(n?n*i:t),height:n||(a?a/i:e)}}async#e(t){return t instanceof Image?t:e.#t.has(t)?e.#t.get(t):new Promise(((a,n)=>{const i=new Image;i.crossOrigin="anonymous",i.src=t,i.onload=()=>{this.config.cache&&e.#t.set(t,i),a(i)},i.onerror=n}))}#n(t,e){const a="undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(t,e):document.createElement("canvas");a.width=t,a.height=e;const n=a.getContext("2d",{willReadFrequently:this.config.willReadFrequently});return n.imageSmoothingEnabled=this.config.imageSmoothing,{canvas:a,context:n}}#i(t,e,a){t.clearRect(0,0,a.width,a.height),t.drawImage(e,0,0,e.naturalWidth,e.naturalHeight,0,0,a.width,a.height)}#s(t){const e=t.data,a=[],{width:n,height:i}=t;for(let t=0;t<i;t++)for(let s=0;s<n;s++){0!==e[4*(t*n+s)+3]&&(this.#h(s,t,n,i,e)&&a.push(s,t))}return a}#h(t,e,a,n,i){return[[-1,-1],[0,-1],[1,-1],[-1,0],[1,0],[-1,1],[0,1],[1,1]].some((([s,o])=>{const r=t+s,h=e+o;if(r<0||r>=a||h<0||h>=n)return!0;return 0===i[4*(h*a+r)+3]}))}#o(t,e,a){const{canvas:n,context:i}=this.#n(a.width+2*this.config.strokeWidth,a.height+2*this.config.strokeWidth);return i.save(),i.translate(this.config.strokeWidth,this.config.strokeWidth),i.beginPath(),i.strokeStyle=this.config.strokeColor,i.lineWidth=this.config.strokeWidth,i.lineJoin="round",i.lineCap="round",e.forEach(((t,a)=>{a%2==0&&(i.moveTo(t,e[a+1]),i.lineTo(t+1,e[a+1]))})),i.stroke(),i.restore(),i.drawImage(t,this.config.strokeWidth,this.config.strokeWidth,a.width,a.height),n}#r(t){return new Promise((async e=>{const a=new Image;a.onload=()=>e(a),a.src=await this.#c(t)}))}#c(t){return t instanceof OffscreenCanvas?t.convertToBlob().then(URL.createObjectURL):t.toDataURL()}}export{e as default};