Advertisement
rg443

javascript hermite resize

May 11th, 2017
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Hermite resize - fast image resize/resample using Hermite filter. 1 cpu version!
  3.  *
  4.  * @param {HtmlElement} canvas
  5.  * @param {int} width
  6.  * @param {int} height
  7.  * @param {boolean} resize_canvas if true, canvas will be resized. Optional.
  8.  */
  9. function resample_single(canvas, width, height, resize_canvas) {
  10.     var width_source = canvas.width;
  11.     var height_source = canvas.height;
  12.     width = Math.round(width);
  13.     height = Math.round(height);
  14.  
  15.     var ratio_w = width_source / width;
  16.     var ratio_h = height_source / height;
  17.     var ratio_w_half = Math.ceil(ratio_w / 2);
  18.     var ratio_h_half = Math.ceil(ratio_h / 2);
  19.  
  20.     var ctx = canvas.getContext("2d");
  21.     var img = ctx.getImageData(0, 0, width_source, height_source);
  22.     var img2 = ctx.createImageData(width, height);
  23.     var data = img.data;
  24.     var data2 = img2.data;
  25.  
  26.     for (var j = 0; j < height; j++) {
  27.         for (var i = 0; i < width; i++) {
  28.             var x2 = (i + j * width) * 4;
  29.             var weight = 0;
  30.             var weights = 0;
  31.             var weights_alpha = 0;
  32.             var gx_r = 0;
  33.             var gx_g = 0;
  34.             var gx_b = 0;
  35.             var gx_a = 0;
  36.             var center_y = (j + 0.5) * ratio_h;
  37.             var yy_start = Math.floor(j * ratio_h);
  38.             var yy_stop = Math.ceil((j + 1) * ratio_h);
  39.             for (var yy = yy_start; yy < yy_stop; yy++) {
  40.                 var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half;
  41.                 var center_x = (i + 0.5) * ratio_w;
  42.                 var w0 = dy * dy; //pre-calc part of w
  43.                 var xx_start = Math.floor(i * ratio_w);
  44.                 var xx_stop = Math.ceil((i + 1) * ratio_w);
  45.                 for (var xx = xx_start; xx < xx_stop; xx++) {
  46.                     var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half;
  47.                     var w = Math.sqrt(w0 + dx * dx);
  48.                     if (w >= 1) {
  49.                         //pixel too far
  50.                         continue;
  51.                     }
  52.                     //hermite filter
  53.                     weight = 2 * w * w * w - 3 * w * w + 1;
  54.                     var pos_x = 4 * (xx + yy * width_source);
  55.                     //alpha
  56.                     gx_a += weight * data[pos_x + 3];
  57.                     weights_alpha += weight;
  58.                     //colors
  59.                     if (data[pos_x + 3] < 255)
  60.                         weight = weight * data[pos_x + 3] / 250;
  61.                     gx_r += weight * data[pos_x];
  62.                     gx_g += weight * data[pos_x + 1];
  63.                     gx_b += weight * data[pos_x + 2];
  64.                     weights += weight;
  65.                 }
  66.             }
  67.             data2[x2] = gx_r / weights;
  68.             data2[x2 + 1] = gx_g / weights;
  69.             data2[x2 + 2] = gx_b / weights;
  70.             data2[x2 + 3] = gx_a / weights_alpha;
  71.         }
  72.     }
  73.     //clear and resize canvas
  74.     if (resize_canvas === true) {
  75.         canvas.width = width;
  76.         canvas.height = height;
  77.     } else {
  78.         ctx.clearRect(0, 0, width_source, height_source);
  79.     }
  80.  
  81.     //draw
  82.     ctx.putImageData(img2, 0, 0);
  83. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement