forked from: Lanczos Resampling
forked from Lanczos Resampling (diff: 4)
more on http://blog.yoz.sk/2010/11/lanczos-resampling-with-actionscript/
ActionScript3 source code
/**
* Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qLhi
*/
// forked from jozefchutka's Lanczos Resampling
/*
more on
http://blog.yoz.sk/2010/11/lanczos-resampling-with-actionscript/
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.text.TextField;
[SWF(width="465", height="465", frameRate="30", backgroundColor="#FFFFFF")]
public class WonderflApp extends Sprite
{
public var original:Loader = new Loader();
public var tf:TextField = new TextField();
public function WonderflApp():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var request:URLRequest = new URLRequest();
request.url = "http://sphotos.ak.fbcdn.net/hphotos-ak-snc4/hs061.snc4/34435_824223712001_9021630_46770431_3138463_n.jpg";
original.load(request, new LoaderContext(true));
original.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
addChild(tf);
tf.appendText("Loading ...\n");
}
public function onComplete(event:Event):void
{
original.width = original.height = 500;
addChild(original);
var originalBitmapData:BitmapData = Bitmap(original.content).bitmapData;
LanczosBitmapDataResizer.FILTER_SIZE = 1;
// RESIZING:
var d0:Date = new Date();
var bitmapData:BitmapData = LanczosBitmapDataResizer.resize(originalBitmapData, 227, 227);
var d1:Date = new Date();
var result:Bitmap = new Bitmap(bitmapData);
result.x = original.x + original.width - 150;
addChild(result);
tf.appendText("Resizing " + originalBitmapData.width + "x"
+ originalBitmapData.height + "px to " + result.bitmapData.width
+ "x" + result.bitmapData.height + "px ...\n");
tf.appendText("Resizing finished in " + String(d1.time - d0.time) + " ms");
tf.multiline = true;
tf.y = original.height + 10;
tf.height = 100;
tf.width = original.width * 2 + 10;
tf.background = true;
tf.border = true;
}
}
}
import flash.display.BitmapData;
import flash.utils.Dictionary;
internal class LanczosBitmapDataResizer
{
public static var CACHE:Dictionary = new Dictionary();
public static var CACHE_PRECISION:uint = 100;
public static var FILTER_SIZE:uint = 1;
public function LanczosBitmapDataResizer()
{
}
public static function lanczos(filterSize:uint, x:Number):Number
{
if(x >= filterSize || x <= -filterSize)
return 0;
if(x == 0)
return 1;
var xpi:Number = x * Math.PI;
return filterSize * Math.sin(xpi) * Math.sin(xpi / filterSize)
/ (xpi * xpi);
}
public static function resize(source:BitmapData, width:uint,
height:uint):BitmapData
{
var total:Number, distanceX:Number, distanceY:Number, value:Number;
var a:Number, r:Number, g:Number, b:Number;
var i:uint, color:uint, cacheKey:uint;
var cache:Dictionary = CACHE;
var cachePrecision:uint = CACHE_PRECISION;
var filterSize:uint = FILTER_SIZE;
var x:uint, x1:uint, x1b:int, x1e:int;
var y:uint, y1:uint, y1b:int, y1e:int, y2:uint, y3:uint;
var distance:Number;
var values:Vector.<Number> = new Vector.<Number>();
var sx:Number = width / source.width;
var sy:Number = height / source.height;
var sw1:uint = source.width - 1;
var sh1:uint = source.height - 1;
var isx:Number = 1 / sx;
var isy:Number = 1 / sy;
var cw:Number = 1 / width;
var ch:Number = 1 / height;
var csx:Number = Math.min(1, sx);
var csy:Number = Math.min(1, sy);
var cx:Number, cy:Number;
var sourcePixelX:Number, sourcePixelY:Number;
var sourcePixels:Vector.<uint> = source.getVector(source.rect);
var output:BitmapData =
new BitmapData(width, height, source.transparent);
var outputPixels:Vector.<uint> =
new Vector.<uint>(width * height, true);
for(y = 0; y < height; y++)
{
sourcePixelY = (y + 0.5) * isy;
y1b = int(sourcePixelY - filterSize);
if(y1b < 0)
y1b = 0;
y1e = Math.ceil(sourcePixelY + filterSize);
if(y1e > sh1)
y1e = sh1;
cy = y * ch - sourcePixelY;
y3 = y * width;
for(x = 0; x < width; x++)
{
sourcePixelX = (x + 0.5) * isx;
x1b = int(sourcePixelX - filterSize);
if(x1b < 0)
x1b = 0;
x1e = Math.ceil(sourcePixelX + filterSize);
if(x1e > sw1)
x1e = sw1;
cx = x * cw - sourcePixelX;
values.length = i = total = 0;
for(y1 = y1b; y1 <= y1e; y1++)
{
distanceY = (y1 + cy) * csy;
for(x1 = x1b; x1 <= x1e; x1++)
{
distanceX = (x1 + cx) * csx;
distance = distanceX * distanceX
+ distanceY * distanceY;
cacheKey = distance * cachePrecision;
if(cache[cacheKey] != null)
{
value = cache[cacheKey];
}
else
{
distance = Math.sqrt(distance);
value = lanczos(filterSize, distance);
if(value < 0)
value = 0;
cache[cacheKey] = value;
}
values[uint(i++)] = value;
total += value;
}
}
total = 1 / total;
i = a = r = g = b = 0;
for(y1 = y1b; y1 <= y1e; y1++)
{
y2 = y1 * source.width;
for(x1 = x1b; x1 <= x1e; x1++)
{
color = sourcePixels[uint(y2 + x1)];
value = values[uint(i++)] * total;
a += (color >> 24 & 0xff) * value;
r += (color >> 16 & 0xff) * value;
g += (color >> 8 & 0xff) * value;
b += (color & 0xff) * value;
}
}
outputPixels[uint(x + y3)] =
int(a) << 24 | int(r) << 16 | int(g) << 8 | int(b);
}
}
output.setVector(output.rect, outputPixels);
return output;
}
}