UNPKG

edgeit.js

Version:

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

2 lines (1 loc) 2.18 kB
"use strict";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:i}=e,n=this.#a(a,i),{canvas:s,context:o}=this.#i(n.width,n.height);this.#n(o,e,n);const r=o.getImageData(0,0,n.width,n.height),h=this.#s(r),c=this.#o(e,h,n);return this.#r(c)}catch(t){throw t}}#a(t,e){const{width:a,height:i}=this.config,n=t/e;return{width:a||(i?i*n:t),height:i||(a?a/n:e)}}async#e(t){return t instanceof Image?t:e.#t.has(t)?e.#t.get(t):new Promise(((a,i)=>{const n=new Image;n.crossOrigin="anonymous",n.src=t,n.onload=()=>{this.config.cache&&e.#t.set(t,n),a(n)},n.onerror=i}))}#i(t,e){const a="undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(t,e):document.createElement("canvas");a.width=t,a.height=e;const i=a.getContext("2d",{willReadFrequently:this.config.willReadFrequently});return i.imageSmoothingEnabled=this.config.imageSmoothing,{canvas:a,context:i}}#n(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:i,height:n}=t;for(let t=0;t<n;t++)for(let s=0;s<i;s++){0!==e[4*(t*i+s)+3]&&(this.#h(s,t,i,n,e)&&a.push(s,t))}return a}#h(t,e,a,i,n){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>=i)return!0;return 0===n[4*(h*a+r)+3]}))}#o(t,e,a){const{canvas:i,context:n}=this.#i(a.width+2*this.config.strokeWidth,a.height+2*this.config.strokeWidth);return n.save(),n.translate(this.config.strokeWidth,this.config.strokeWidth),n.beginPath(),n.strokeStyle=this.config.strokeColor,n.lineWidth=this.config.strokeWidth,n.lineJoin="round",n.lineCap="round",e.forEach(((t,a)=>{a%2==0&&(n.moveTo(t,e[a+1]),n.lineTo(t+1,e[a+1]))})),n.stroke(),n.restore(),n.drawImage(t,this.config.strokeWidth,this.config.strokeWidth,a.width,a.height),i}#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()}}module.exports=e;