Guest User

Slight optimization of Lanczos Code on http://blog.yoz.sk/2010/11/lanczos-resampling-with-actionscript/

a guest
Nov 10th, 2010
468
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package sk.yoz.image
  2. {
  3.     import flash.display.BitmapData;
  4.     import flash.utils.Dictionary;
  5.    
  6.     public class LanczosBitmapDataResizer
  7.     {
  8.         public static var CACHE:Dictionary = new Dictionary();
  9.         public static var CACHE_PRECISION:uint = 100;
  10.         public static var FILTER_SIZE:uint = 1;
  11.        
  12.         public function LanczosBitmapDataResizer()
  13.         {
  14.         }
  15.        
  16.         public static function resize(source:BitmapData, width:uint, height:uint ):BitmapData
  17.         {
  18.             var total:Number, distanceX:Number, distanceY:Number, value:Number;
  19.             var a:Number, r:Number, g:Number, b:Number;
  20.             var i:uint, color:uint, cacheKey:uint;
  21.             var cache:Dictionary = CACHE;
  22.             var cachePrecision:uint = CACHE_PRECISION;
  23.             var filterSize:uint = FILTER_SIZE;
  24.             var filterSizeSq:uint = filterSize * filterSize;
  25.            
  26.             var x:uint, x1:uint, x1b:int, x1e:int;
  27.             var y:uint, y1:uint, y1b:int, y1e:int, y2:uint, y3:uint;
  28.             var distance:Number;
  29.            
  30.             var values:Vector.<Number> = new Vector.<Number>();
  31.             var sx:Number = width / source.width;
  32.             var sy:Number = height / source.height;
  33.             var sw1:uint = source.width - 1;
  34.             var sh1:uint = source.height - 1;
  35.             var isx:Number = 1 / sx;
  36.             var isy:Number = 1 / sy;
  37.             var cw:Number = 1 / width;
  38.             var ch:Number = 1 / height;
  39.             var csx:Number = Math.min(1, sx);
  40.             var csy:Number = Math.min(1, sy);
  41.             var cx:Number, cy:Number;
  42.             var PI:Number = Math.PI;
  43.             var sourcePixelX:Number, sourcePixelY:Number;
  44.             var sourcePixels:Vector.<uint> = source.getVector(source.rect);
  45.             var output:BitmapData =
  46.                 new BitmapData(width, height, source.transparent);
  47.             var outputPixels:Vector.<uint> =
  48.                 new Vector.<uint>(width * height, true);
  49.            
  50.             for(y = 0; y < height; y++)
  51.             {
  52.                 sourcePixelY = (y + 0.5) * isy;
  53.                 y1b = int(sourcePixelY - filterSize);
  54.                 if(y1b < 0)
  55.                     y1b = 0;
  56.                 y1e = -int(-(sourcePixelY + filterSize));
  57.                 if(y1e > sh1)
  58.                     y1e = sh1;
  59.                 cy = y * ch - sourcePixelY;
  60.                 y3 = y * width;
  61.                
  62.                 for(x = 0; x < width; x++)
  63.                 {
  64.                     sourcePixelX = (x + 0.5) * isx;
  65.                     x1b = int(sourcePixelX - filterSize);
  66.                     if(x1b < 0)
  67.                         x1b = 0;
  68.                     x1e = -int(-(sourcePixelX + filterSize));
  69.                     if(x1e > sw1)
  70.                         x1e = sw1;
  71.                     cx = x * cw - sourcePixelX;
  72.                    
  73.                     values.length = i = total = 0;
  74.                     for(y1 = y1b; y1 <= y1e; y1++)
  75.                     {
  76.                         distanceY = (y1 + cy) * csy;
  77.                         distanceY *= distanceY;
  78.                         for(x1 = x1b; x1 <= x1e; x1++)
  79.                         {
  80.                             distanceX = (x1 + cx) * csx;
  81.                             distance = distanceX * distanceX + distanceY;
  82.                             cacheKey = distance * cachePrecision;
  83.                             if(cache[cacheKey] != null)
  84.                             {
  85.                                 value = cache[cacheKey];
  86.                             }
  87.                             else
  88.                             {
  89.                                 if(distance >= filterSizeSq || distance <= -filterSizeSq)
  90.                                     value = 0;
  91.                                 else if(distance == 0)
  92.                                     value =  1;
  93.                                 else
  94.                                 {
  95.                                     var xpi:Number = Math.sqrt(distance) * PI;
  96.                                     value = filterSize * Math.sin(xpi) * Math.sin(xpi / filterSize) / (distance * PI * PI);
  97.                                     if( value < 0) value = 0;
  98.                                 }
  99.                                 cache[cacheKey] = value;
  100.                             }
  101.                            
  102.                             values[uint(i++)] = value;
  103.                             total += value;
  104.                         }
  105.                     }
  106.                    
  107.                     total = 1 / total;
  108.                    
  109.                     i = a = r = g = b = 0;
  110.                     for(y1 = y1b; y1 <= y1e; y1++)
  111.                     {
  112.                         y2 = y1 * source.width;
  113.                         for(x1 = x1b; x1 <= x1e; x1++)
  114.                         {
  115.                             color = sourcePixels[uint(y2 + x1)];
  116.                             value = values[uint(i++)] * total;
  117.                             a += (color >> 24 & 0xff) * value;
  118.                             r += (color >> 16 & 0xff) * value;
  119.                             g += (color >> 8 & 0xff) * value;
  120.                             b += (color & 0xff) * value;
  121.                         }
  122.                     }
  123.                    
  124.                     outputPixels[uint(x + y3)] =
  125.                         int(a) << 24 | int(r) << 16 | int(g) << 8 | int(b);
  126.                 }
  127.             }
  128.            
  129.             output.setVector(output.rect, outputPixels);
  130.             return output;
  131.         }
  132.     }
  133. }
Add Comment
Please, Sign In to add comment