Skip to content

Instantly share code, notes, and snippets.

@didierbrun
Created December 27, 2009 11:49
Show Gist options
  • Select an option

  • Save didierbrun/264250 to your computer and use it in GitHub Desktop.

Select an option

Save didierbrun/264250 to your computer and use it in GitHub Desktop.
/**
*
*
* ScaleBitmap
*
* @author Didier Brun
* @author Jerôme Decoster
* @version 1.1
*
*/
package org.bytearray.display
{
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Rectangle;
public class ScaleBitmap
{
//--------------------------------------
// PUBLIC
//--------------------------------------
/**
* @param bitmapData BitmapData source
* @param graphics Graphics to draw
* @param width Draw width
* @param height Draw height
* @param inner Inner rectangle (relative to 0,0)
* @param outer Outer rectangle (relative to 0,0)
* @param smooth If <code>false</code>, upscaled bitmap images are rendered by using a nearest-neighbor
* algorithm and look pixelated. If <code>true</code>, upscaled bitmap images are rendered by using a
* bilinear algorithm. Rendering by using the nearest neighbor algorithm is usually faster.
*/
public static function draw(bitmapData:BitmapData,
graphics:Graphics,
width:Number,
height:Number,
inner:Rectangle,
outer:Rectangle = null,
smooth:Boolean = false):void
{
// some useful local vars
var x:int, y:int;
var ox:Number = 0, oy:Number;
var dx:Number = 0, dy:Number;
var wid:Number, hei:Number;
var dwid:Number, dhei:Number;
var sw:int = bitmapData.width;
var sh:int = bitmapData.height;
var mat:Matrix = new Matrix();
var widths:Array = [inner.left + 1,
inner.width - 2,
sw - inner.right + 1];
var heights:Array = [inner.top + 1,
inner.height - 2,
sh - inner.bottom + 1];
var rx:Number = width - widths[0] - widths[2];
var ry:Number = height - heights[0] - heights[2];
var ol:Number = (outer != null) ? -outer.left : 0;
var ot:Number = (outer != null) ? -outer.top : 0;
// let's draw
for (x; x < 3 ;x++)
{
// original width
wid = widths[x];
// draw width
dwid = x==1 ? rx : wid;
// original & draw offset
dy = oy = 0;
mat.a = dwid / wid;
for (y = 0; y < 3; y++)
{
// original height
hei = heights[y];
// draw height
dhei = y==1 ? ry : hei;
if (dwid > 0 && dhei > 0)
{
// some matrix computation
mat.d = dhei / hei;
mat.tx = -ox * mat.a + dx;
mat.ty = -oy * mat.d + dy;
mat.translate(ol, ot);
// draw the cell
graphics.beginBitmapFill(bitmapData, mat, false, smooth);
graphics.drawRect(dx + ol, dy + ot, dwid, dhei);
}
// offset incrementation
oy += hei;
dy += dhei;
}
// offset incrementation
ox += wid;
dx += dwid;
}
graphics.endFill();
}
}
}
/**
*
*
* ScaleBitmapSprite
*
* @author Didier Brun
* @author Jerôme Decoster
* @version 1.1
*
*/
package org.bytearray.display {
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
public class ScaleBitmapSprite extends Sprite
{
private var _bitmapData:BitmapData;
private var _height:Number;
private var _width:Number;
private var inner:Rectangle;
private var minHeight:Number;
private var minWidth:Number;
private var outer:Rectangle;
private var outerHeight:Number;
private var outerWidth:Number;
private var smooth:Boolean;
/**
* @param bitmapData BitmapData source
* @param inner Inner rectangle (relative to 0,0)
* @param outer Outer rectangle (relative to 0,0)
* @param smooth If <code>false</code>, upscaled bitmap images are rendered by using a nearest-neighbor
* algorithm and look pixelated. If <code>true</code>, upscaled bitmap images are rendered by using a
* bilinear algorithm. Rendering by using the nearest neighbor algorithm is usually faster.
*/
function ScaleBitmapSprite(bitmapData:BitmapData,
inner:Rectangle,
outer:Rectangle = null,
smooth:Boolean = false)
{
_bitmapData = bitmapData;
this.inner = inner;
this.outer = outer;
this.smooth = smooth;
if (outer != null)
{
_width = outer.width;
_height = outer.height;
outerWidth = bitmapData.width - outer.width;
outerHeight = bitmapData.height - outer.height;
}
else
{
_width = inner.width;
_height = inner.height;
outerWidth = 0;
outerHeight = 0;
}
minWidth = bitmapData.width - inner.width - outerWidth + 2;
minHeight = bitmapData.height - inner.height - outerHeight + 2;
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
//--------------------------------------
// EVENTS
//--------------------------------------
private function onAddedToStage(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
addEventListener(Event.RENDER, onRender);
onRender();
}
private function onRemovedFromStage(event:Event):void
{
removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
removeEventListener(Event.RENDER, onRender);
}
private function onRender(event:Event = null):void
{
graphics.clear();
/*
* Math.floor optimisation (works only with positive values)
*
* Slower 1733ms
* var test:Number = Math.floor(1.5);
*
* Fastest 145ms
* var test:int = 1.5 >> 0;
*/
ScaleBitmap.draw(_bitmapData,
graphics,
(_width + outerWidth) >> 0,
(_height + outerHeight) >> 0,
inner,
outer,
smooth);
}
//--------------------------------------
// PUBLIC
//--------------------------------------
/**
* setter deactivated
*/
override public function set scaleX(value:Number):void
{
}
/**
* setter deactivated
*/
override public function set scaleY(value:Number):void
{
}
/**
* @inheritDoc
*/
override public function get width():Number{ return _width; }
/**
* @inheritDoc
*/
override public function set width(value:Number):void
{
_width = value > minWidth ? value : minWidth;
if (stage != null) stage.invalidate();
}
/**
* @inheritDoc
*/
override public function get height():Number{ return _height; }
/**
* @inheritDoc
*/
override public function set height(value:Number):void
{
_height = value > minHeight ? value : minHeight;
if (stage != null) stage.invalidate();
}
/**
* The BitmapData object being referenced.
*/
public function get bitmapData():BitmapData{ return _bitmapData; }
public function set bitmapData(value:BitmapData):void
{
_bitmapData = value;
if (stage != null) stage.invalidate();
}
}
}
@seyoung-hyun
Copy link
Copy Markdown

Hi @didierbrun,
Thank you for sharing the code :)
Can I use your code in my commercial app?
Please let me know how I can use the code for commercial distribution.
Thanks.

@jojobobby
Copy link
Copy Markdown

Thanks for keeping this up.
With flash being gone, there are not many as3 code examples around anymore and is very hard to find something this valuable.

@didierbrun
Copy link
Copy Markdown
Author

@jojobobby You're welcome :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment