Advertisement
rg443

javascript lanczos

May 11th, 2017
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // returns a function that calculates lanczos weight
  2. function lanczosCreate(lobes) {
  3.     return function(x) {
  4.         if (x > lobes)
  5.             return 0;
  6.         x *= Math.PI;
  7.         if (Math.abs(x) < 1e-16)
  8.             return 1;
  9.         var xx = x / lobes;
  10.         return Math.sin(x) * Math.sin(xx) / x / xx;
  11.     };
  12. }
  13.  
  14. // elem: canvas element, img: image element, sx: scaled width, lobes: kernel radius
  15. function thumbnailer(elem, img, sx, lobes) {
  16.     this.canvas = elem;
  17.     elem.width = img.width;
  18.     elem.height = img.height;
  19.     elem.style.display = "none";
  20.     this.ctx = elem.getContext("2d");
  21.     this.ctx.drawImage(img, 0, 0);
  22.     this.img = img;
  23.     this.src = this.ctx.getImageData(0, 0, img.width, img.height);
  24.     this.dest = {
  25.         width : sx,
  26.         height : Math.round(img.height * sx / img.width),
  27.     };
  28.     this.dest.data = new Array(this.dest.width * this.dest.height * 3);
  29.     this.lanczos = lanczosCreate(lobes);
  30.     this.ratio = img.width / sx;
  31.     this.rcp_ratio = 2 / this.ratio;
  32.     this.range2 = Math.ceil(this.ratio * lobes / 2);
  33.     this.cacheLanc = {};
  34.     this.center = {};
  35.     this.icenter = {};
  36.     setTimeout(this.process1, 0, this, 0);
  37. }
  38.  
  39. thumbnailer.prototype.process1 = function(self, u) {
  40.     self.center.x = (u + 0.5) * self.ratio;
  41.     self.icenter.x = Math.floor(self.center.x);
  42.     for (var v = 0; v < self.dest.height; v++) {
  43.         self.center.y = (v + 0.5) * self.ratio;
  44.         self.icenter.y = Math.floor(self.center.y);
  45.         var a, r, g, b;
  46.         a = r = g = b = 0;
  47.         for (var i = self.icenter.x - self.range2; i <= self.icenter.x + self.range2; i++) {
  48.             if (i < 0 || i >= self.src.width)
  49.                 continue;
  50.             var f_x = Math.floor(1000 * Math.abs(i - self.center.x));
  51.             if (!self.cacheLanc[f_x])
  52.                 self.cacheLanc[f_x] = {};
  53.             for (var j = self.icenter.y - self.range2; j <= self.icenter.y + self.range2; j++) {
  54.                 if (j < 0 || j >= self.src.height)
  55.                     continue;
  56.                 var f_y = Math.floor(1000 * Math.abs(j - self.center.y));
  57.                 if (self.cacheLanc[f_x][f_y] == undefined)
  58.                     self.cacheLanc[f_x][f_y] = self.lanczos(Math.sqrt(Math.pow(f_x * self.rcp_ratio, 2)
  59.                             + Math.pow(f_y * self.rcp_ratio, 2)) / 1000);
  60.                 weight = self.cacheLanc[f_x][f_y];
  61.                 if (weight > 0) {
  62.                     var idx = (j * self.src.width + i) * 4;
  63.                     a += weight;
  64.                     r += weight * self.src.data[idx];
  65.                     g += weight * self.src.data[idx + 1];
  66.                     b += weight * self.src.data[idx + 2];
  67.                 }
  68.             }
  69.         }
  70.         var idx = (v * self.dest.width + u) * 3;
  71.         self.dest.data[idx] = r / a;
  72.         self.dest.data[idx + 1] = g / a;
  73.         self.dest.data[idx + 2] = b / a;
  74.     }
  75.  
  76.     if (++u < self.dest.width)
  77.         setTimeout(self.process1, 0, self, u);
  78.     else
  79.         setTimeout(self.process2, 0, self);
  80. };
  81. thumbnailer.prototype.process2 = function(self) {
  82.     self.canvas.width = self.dest.width;
  83.     self.canvas.height = self.dest.height;
  84.     self.ctx.drawImage(self.img, 0, 0, self.dest.width, self.dest.height);
  85.     self.src = self.ctx.getImageData(0, 0, self.dest.width, self.dest.height);
  86.     var idx, idx2;
  87.     for (var i = 0; i < self.dest.width; i++) {
  88.         for (var j = 0; j < self.dest.height; j++) {
  89.             idx = (j * self.dest.width + i) * 3;
  90.             idx2 = (j * self.dest.width + i) * 4;
  91.             self.src.data[idx2] = self.dest.data[idx];
  92.             self.src.data[idx2 + 1] = self.dest.data[idx + 1];
  93.             self.src.data[idx2 + 2] = self.dest.data[idx + 2];
  94.         }
  95.     }
  96.     self.ctx.putImageData(self.src, 0, 0);
  97.     self.canvas.style.display = "block";
  98. };
  99.  
  100.  
  101. img.onload = function() {
  102.     var canvas = document.createElement("canvas");
  103.     new thumbnailer(canvas, img, 188, 3); //this produces lanczos3
  104.     document.body.appendChild(canvas);
  105. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement