fabric
Version:
Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.
3 lines (2 loc) • 5.34 kB
JavaScript
import{defineProperty as t}from"../../_virtual/_rollupPluginBabelHelpers.min.mjs";import{BaseFilter as e}from"./BaseFilter.min.mjs";import{isWebGLPipelineState as a}from"./utils.min.mjs";import{classRegistry as s}from"../ClassRegistry.min.mjs";import{createCanvasElement as i}from"../util/misc/dom.min.mjs";const r={resizeType:"hermite",scaleX:1,scaleY:1,lanczosLobes:3};class o extends e{sendUniformData(t,e){t.uniform2fv(e.uDelta,this.horizontal?[1/this.width,0]:[0,1/this.height]),t.uniform1fv(e.uTaps,this.taps)}getFilterWindow(){const t=this.tempScale;return Math.ceil(this.lanczosLobes/t)}getCacheKey(){const t=this.getFilterWindow();return`${this.type}_${t}`}getFragmentSource(){const t=this.getFilterWindow();return this.generateShader(t)}getTaps(){const t=this.lanczosCreate(this.lanczosLobes),e=this.tempScale,a=this.getFilterWindow(),s=new Array(a);for(let i=1;i<=a;i++)s[i-1]=t(i*e);return s}generateShader(t){const e=new Array(t);for(let a=1;a<=t;a++)e[a-1]=`${a}.0 * uDelta`;return`\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[${t}];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ${e.map((t,e)=>`\n color += texture2D(uTexture, vTexCoord + ${t}) * uTaps[${e}] + texture2D(uTexture, vTexCoord - ${t}) * uTaps[${e}];\n sum += 2.0 * uTaps[${e}];\n `).join("\n")}\n gl_FragColor = color / sum;\n }\n `}applyToForWebgl(t){t.passes++,this.width=t.sourceWidth,this.horizontal=!0,this.dW=Math.round(this.width*this.scaleX),this.dH=t.sourceHeight,this.tempScale=this.dW/this.width,this.taps=this.getTaps(),t.destinationWidth=this.dW,super.applyTo(t),t.sourceWidth=t.destinationWidth,this.height=t.sourceHeight,this.horizontal=!1,this.dH=Math.round(this.height*this.scaleY),this.tempScale=this.dH/this.height,this.taps=this.getTaps(),t.destinationHeight=this.dH,super.applyTo(t),t.sourceHeight=t.destinationHeight}applyTo(t){a(t)?this.applyToForWebgl(t):this.applyTo2d(t)}isNeutralState(){return 1===this.scaleX&&1===this.scaleY}lanczosCreate(t){return e=>{if(e>=t||e<=-t)return 0;if(e<1.1920929e-7&&e>-1.1920929e-7)return 1;const a=(e*=Math.PI)/t;return Math.sin(e)/e*Math.sin(a)/a}}applyTo2d(t){const e=t.imageData,a=this.scaleX,s=this.scaleY;this.rcpScaleX=1/a,this.rcpScaleY=1/s;const i=e.width,r=e.height,o=Math.round(i*a),h=Math.round(r*s);let l;l="sliceHack"===this.resizeType?this.sliceByTwo(t,i,r,o,h):"hermite"===this.resizeType?this.hermiteFastResize(t,i,r,o,h):"bilinear"===this.resizeType?this.bilinearFiltering(t,i,r,o,h):"lanczos"===this.resizeType?this.lanczosResize(t,i,r,o,h):new ImageData(o,h),t.imageData=l}sliceByTwo(t,e,a,s,r){const o=t.imageData,h=.5;let l=!1,n=!1,c=e*h,u=a*h;const p=t.filterBackend.resources;let m=0,d=0;const f=e;let g=0;p.sliceByTwo||(p.sliceByTwo=i());const M=p.sliceByTwo;(M.width<1.5*e||M.height<a)&&(M.width=1.5*e,M.height=a);const T=M.getContext("2d");for(T.clearRect(0,0,1.5*e,a),T.putImageData(o,0,0),s=Math.floor(s),r=Math.floor(r);!l||!n;)e=c,a=u,s<Math.floor(c*h)?c=Math.floor(c*h):(c=s,l=!0),r<Math.floor(u*h)?u=Math.floor(u*h):(u=r,n=!0),T.drawImage(M,m,d,e,a,f,g,c,u),m=f,d=g,g+=u;return T.getImageData(m,d,s,r)}lanczosResize(t,e,a,s,i){const r=t.imageData.data,o=t.ctx.createImageData(s,i),h=o.data,l=this.lanczosCreate(this.lanczosLobes),n=this.rcpScaleX,c=this.rcpScaleY,u=2/this.rcpScaleX,p=2/this.rcpScaleY,m=Math.ceil(n*this.lanczosLobes/2),d=Math.ceil(c*this.lanczosLobes/2),f={},g={x:0,y:0},M={x:0,y:0};return function t(T){let y,x,z,w,D,S,b,F,W,v,C;for(g.x=(T+.5)*n,M.x=Math.floor(g.x),y=0;y<i;y++){for(g.y=(y+.5)*c,M.y=Math.floor(g.y),D=0,S=0,b=0,F=0,W=0,x=M.x-m;x<=M.x+m;x++)if(!(x<0||x>=e)){v=Math.floor(1e3*Math.abs(x-g.x)),f[v]||(f[v]={});for(let t=M.y-d;t<=M.y+d;t++)t<0||t>=a||(C=Math.floor(1e3*Math.abs(t-g.y)),f[v][C]||(f[v][C]=l(Math.sqrt(Math.pow(v*u,2)+Math.pow(C*p,2))/1e3)),z=f[v][C],z>0&&(w=4*(t*e+x),D+=z,S+=z*r[w],b+=z*r[w+1],F+=z*r[w+2],W+=z*r[w+3]))}w=4*(y*s+T),h[w]=S/D,h[w+1]=b/D,h[w+2]=F/D,h[w+3]=W/D}return++T<s?t(T):o}(0)}bilinearFiltering(t,e,a,s,i){let r,o,h,l,n,c,u,p,m,d,f,g,M,T=0;const y=this.rcpScaleX,x=this.rcpScaleY,z=4*(e-1),w=t.imageData.data,D=t.ctx.createImageData(s,i),S=D.data;for(u=0;u<i;u++)for(p=0;p<s;p++)for(n=Math.floor(y*p),c=Math.floor(x*u),m=y*p-n,d=x*u-c,M=4*(c*e+n),f=0;f<4;f++)r=w[M+f],o=w[M+4+f],h=w[M+z+f],l=w[M+z+4+f],g=r*(1-m)*(1-d)+o*m*(1-d)+h*d*(1-m)+l*m*d,S[T++]=g;return D}hermiteFastResize(t,e,a,s,i){const r=this.rcpScaleX,o=this.rcpScaleY,h=Math.ceil(r/2),l=Math.ceil(o/2),n=t.imageData.data,c=t.ctx.createImageData(s,i),u=c.data;for(let t=0;t<i;t++)for(let a=0;a<s;a++){const i=4*(a+t*s);let c=0,p=0,m=0,d=0,f=0,g=0,M=0;const T=(t+.5)*o;for(let s=Math.floor(t*o);s<(t+1)*o;s++){const t=Math.abs(T-(s+.5))/l,i=(a+.5)*r,o=t*t;for(let t=Math.floor(a*r);t<(a+1)*r;t++){let a=Math.abs(i-(t+.5))/h;const r=Math.sqrt(o+a*a);r>1&&r<-1||(c=2*r*r*r-3*r*r+1,c>0&&(a=4*(t+s*e),M+=c*n[a+3],m+=c,n[a+3]<255&&(c=c*n[a+3]/250),d+=c*n[a],f+=c*n[a+1],g+=c*n[a+2],p+=c))}}u[i]=d/p,u[i+1]=f/p,u[i+2]=g/p,u[i+3]=M/m}return c}}t(o,"type","Resize"),t(o,"defaults",r),t(o,"uniformLocations",["uDelta","uTaps"]),s.setClass(o);export{o as Resize,r as resizeDefaultValues};
//# sourceMappingURL=Resize.min.mjs.map