NOV 17
Code Flash

Dealing with PNG images in Flash can sometimes be a pain, especially if you want to scale their bitmapData. The problem is that Flash uses bilinear interpolation to shrink images down, and once you get below 50%, there can be some nasty artifacts. The workaround I discovered this week gets around a lot of these problems – progressive bilinear interpolation.

Many thanks to Maxime Cousinou who figured this out initially. The image on the left has been shrunk to 13% without progressive filtering – the one on the right has been stepped down in 50% increments.

Better Scaling

I’ll take the one on the right. ┬áCode as follows, and you can download a sample here.

var typicalScaling:Sprite = new Sprite();
addChild(typicalScaling);

var modifiedScaling:Sprite = new Sprite();
modifiedScaling.x = 235;
modifiedScaling.y = 5;
addChild(modifiedScaling);

loadTypicalImage();
loadModifiedImage();

function loadTypicalImage():void {
	var loader:Loader = new Loader();
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTypicalLoaderComplete);
	loader.load(new URLRequest('rgbLogo.png'));
}

function onTypicalLoaderComplete(e:Event):void {
	var scalingMatrix:Matrix = new Matrix();
	scalingMatrix.scale(.15, .15);
	var loadedImage:Bitmap = Bitmap(e.target.content);  // Cast the loaded content as a bitmap
	var bitmapData:BitmapData = new BitmapData(loadedImage.width, loadedImage.height, true, 0);
	bitmapData.draw(loadedImage, scalingMatrix, null, null, null, true);
	var tempBitmap:Bitmap = new Bitmap(bitmapData);
	typicalScaling.addChild(tempBitmap);
}

function loadModifiedImage():void {
	var loader:Loader = new Loader();
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onModifiedLoaderComplete);
	loader.load(new URLRequest('rgbLogo.png'));
}

function onModifiedLoaderComplete(e:Event):void {
	var loadedImage:Bitmap = Bitmap(e.target.content);  // Cast the loaded content as a bitmap
	var bitmapData:BitmapData = new BitmapData(loadedImage.width, loadedImage.height, true, 0);
	bitmapData.draw(loadedImage, new Matrix(), null, null, null, true);
	var tempBitmap:Bitmap = new Bitmap(resampleBitmapData(bitmapData,.15));
	modifiedScaling.addChild(tempBitmap);
}

function resampleBitmapData (bmp:BitmapData, ratio:Number, transparent:Boolean = true):BitmapData {
	if (ratio >= 1) {
		return (resizeBitmapData(bmp, ratio, transparent));
	}
	else {
		var bmpData:BitmapData 	= bmp.clone();
		var appliedRatio:Number = 1;

		do {
			if (ratio < 0.5 * appliedRatio) {
				bmpData = resizeBitmapData(bmpData, 0.5, transparent);
				appliedRatio = 0.5 * appliedRatio;
			}
			else {
				bmpData = resizeBitmapData(bmpData, ratio / appliedRatio, transparent);
				appliedRatio = ratio;
			}
		} while (appliedRatio != ratio);
	return (bmpData);
	}
}

function resizeBitmapData (bmp:BitmapData, ratio:Number, transparent:Boolean = true):BitmapData {
	var bmpData:BitmapData = new BitmapData(Math.round(bmp.width * ratio), 
                                                Math.round(bmp.height * ratio), transparent, 0x00FFFFFF);
	var scaleMatrix:Matrix = new Matrix(bmpData.width / bmp.width, 0, 0, bmpData.height / bmp.height, 0, 0);
	var colorTransform:ColorTransform = new ColorTransform();
	bmpData.draw(bmp, scaleMatrix, colorTransform, null, null, true);

	return (bmpData);
}

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>