Skip to content

Instantly share code, notes, and snippets.

@lynxerzhang
Forked from didierbrun/ScaleBitmap.as
Created March 16, 2012 02:49
Show Gist options
  • Save lynxerzhang/2048219 to your computer and use it in GitHub Desktop.
Save lynxerzhang/2048219 to your computer and use it in GitHub Desktop.

Revisions

  1. didierbrun revised this gist May 18, 2010. 2 changed files with 188 additions and 163 deletions.
    143 changes: 72 additions & 71 deletions ScaleBitmap.as
    Original file line number Diff line number Diff line change
    @@ -3,103 +3,99 @@
    *
    * ScaleBitmap
    *
    * @author Didier Brun - http://www.bytearray.org
    * @version 1.0
    * @author Didier Brun
    * @author Jerôme Decoster
    * @version 1.1
    *
    */

    package org.bytearray.display {
    package org.bytearray.display
    {
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    public class ScaleBitmap {

    // ------------------------------------------------
    //
    // ---o public static methods
    //
    // ------------------------------------------------
    import flash.geom.Rectangle;

    public class ScaleBitmap
    {
    //--------------------------------------
    // PUBLIC
    //--------------------------------------

    /**
    * draw
    */
    public static function draw(bitmap : BitmapData, // bitmap data source
    graphic:Graphics, // graphic to draw
    width:Number, // draw width
    height:Number, // draw height
    inner : Rectangle, // inner rectangle (relative to 0,0)
    outer : Rectangle=null):void{ // outer rectangle (relative to 0,0)

    * @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, i:int, j:int;
    var ox:Number=0, oy:Number;
    var dx : Number = 0, dy : Number;
    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 = bitmap.width;
    var sh : int = bitmap.height;
    var dwid:Number, dhei:Number;
    var sw:int = bitmapData.width;
    var sh:int = bitmapData.height;

    // outer null ?
    if (outer==null){
    outer = new Rectangle(0,0,sw,sh);
    }
    var mat:Matrix = new Matrix();

    var widths:Array = [inner.left + 1,
    inner.width - 2,
    sw - inner.right + 1];

    // matrix creation
    var mat : Matrix = new Matrix();
    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;

    // pre-calculate widths
    var widths : Array=[ inner.left,
    inner.width,
    sw - inner.right];

    // pre-calculate heights
    var heights : Array=[ inner.top,
    inner.height,
    sh - inner.bottom];

    // resized part
    var resize : Point=new Point( width - widths[0] - widths[2],
    height - heights[0] - heights[2]);

    // let's draw
    for (x=0;x<3;x++){
    for (x; x < 3 ;x++)
    {
    // original width
    wid = widths[x];

    // draw width
    dwid = x==1 ? resize.x : widths[x];


    dwid = x==1 ? rx : wid;
    // original & draw offset
    dy=oy=0;
    dy = oy = 0;
    mat.a = dwid / wid;

    for (y=0;y<3;y++){
    // original & draw height
    for (y = 0; y < 3; y++)
    {
    // original height
    hei = heights[y];
    dhei = y==1 ? resize.y : heights[y];
    // draw height
    dhei = y==1 ? ry : hei;

    if (dwid > 0 && dhei>0){
    if (dwid > 0 && dhei > 0)
    {
    // some matrix computation
    mat.a=dwid/wid;
    mat.d=dhei/hei;
    mat.tx=-ox*mat.a + dx;
    mat.ty=-oy*mat.d + dy;
    mat.translate(-outer.left,-outer.top);
    mat.d = dhei / hei;
    mat.tx = -ox * mat.a + dx;
    mat.ty = -oy * mat.d + dy;
    mat.translate(ol, ot);

    // draw the cell
    graphic.beginBitmapFill(bitmap,mat,false,true);
    graphic.drawRect(dx - outer.left, dy - outer.top, dwid, dhei);
    graphic.endFill();
    graphics.beginBitmapFill(bitmapData, mat, false, smooth);
    graphics.drawRect(dx + ol, dy + ot, dwid, dhei);
    }


    // offset incrementation
    oy += hei;
    dy += dhei;
    @@ -109,6 +105,11 @@ package org.bytearray.display {
    ox += wid;
    dx += dwid;
    }

    graphics.endFill();
    }
    }
    }
    }



    208 changes: 116 additions & 92 deletions ScaleBitmapSprite.as
    Original file line number Diff line number Diff line change
    @@ -3,142 +3,166 @@
    *
    * ScaleBitmapSprite
    *
    * @author Didier Brun - http://www.bytearray.org
    * @version 1.0
    * @author Didier Brun
    * @author Jerôme Decoster
    * @version 1.1
    *
    */

    package org.bytearray.display {
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.geom.Rectangle;
    import flash.events.Event;
    import flash.geom.Rectangle;

    public class ScaleBitmapSprite extends Sprite {
    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;


    // ------------------------------------------------
    //
    // ---o properties
    //
    // ------------------------------------------------

    private var _width : Number;
    private var _height : Number;
    private var _inner : Rectangle;
    private var _outer : Rectangle;
    private var _bitmapData : BitmapData;
    private var _outerWidth : Number;
    private var _outerHeight : Number;
    private var _minWidth : Number;
    private var _minHeight : Number;

    // ------------------------------------------------
    //
    // ---o constructor
    //
    // ------------------------------------------------

    function ScaleBitmapSprite( bitmap : BitmapData,
    inner : Rectangle,
    outer : Rectangle=null) {

    _inner = inner;
    _outer = outer;
    _bitmapData = bitmap;
    /**
    * @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){
    if (outer != null)
    {
    _width = outer.width;
    _height = outer.height;
    _outerWidth = bitmap.width - outer.width;
    _outerHeight = bitmap.height - outer.height;
    } else {
    outerWidth = bitmapData.width - outer.width;
    outerHeight = bitmapData.height - outer.height;
    }
    else
    {
    _width = inner.width;
    _height = inner.height;
    _outerWidth = 0;
    _outerHeight = 0;
    outerWidth = 0;
    outerHeight = 0;
    }

    _minWidth = bitmap.width - inner.width - _outerWidth;
    _minHeight = bitmap.height - inner.height - _outerHeight;
    minWidth = bitmapData.width - inner.width - outerWidth + 2;
    minHeight = bitmapData.height - inner.height - outerHeight + 2;

    draw();
    addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

    // ------------------------------------------------
    //
    // ---o public methods
    //
    // ------------------------------------------------

    /**
    * draw
    */
    public function draw():void {

    //--------------------------------------
    // 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();

    ScaleBitmap.draw( _bitmapData,
    graphics,
    Math.floor(_width + _outerWidth),
    Math.floor(_height + _outerHeight),
    _inner,
    _outer);
    /*
    * 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);
    }


    // ------------------------------------------------
    //
    // ---o public methods
    //
    // ------------------------------------------------
    //--------------------------------------
    // PUBLIC
    //--------------------------------------

    /**
    * get width
    * setter deactivated
    */
    override public function get width():Number{
    return _width;
    override public function set scaleX(value:Number):void
    {
    }

    /**
    * set width
    * setter deactivated
    */
    override public function set width(w:Number):void {
    _width=Math.max(w,_minWidth);
    draw();
    override public function set scaleY(value:Number):void
    {
    }

    /**
    * get height
    * @inheritDoc
    */
    override public function get height():Number{
    return _height;
    }
    override public function get width():Number{ return _width; }

    /**
    * set height
    * @inheritDoc
    */
    override public function set height(h:Number):void {
    _height=Math.max(h, _minHeight);
    draw();
    override public function set width(value:Number):void
    {
    _width = value > minWidth ? value : minWidth;
    if (stage != null) stage.invalidate();
    }

    /**
    * get bitmapData
    * @inheritDoc
    */
    public function get bitmapData() : BitmapData{
    return _bitmapData;
    }
    override public function get height():Number{ return _height; }

    /**
    * set bitmapData
    * @inheritDoc
    */
    public function set bitmapData(b : BitmapData) : void {

    _bitmapData=b;
    draw();

    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();
    }
    }
    }
  2. didierbrun created this gist Dec 27, 2009.
    114 changes: 114 additions & 0 deletions ScaleBitmap.as
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,114 @@
    /**
    *
    *
    * ScaleBitmap
    *
    * @author Didier Brun - http://www.bytearray.org
    * @version 1.0
    *
    */

    package org.bytearray.display {
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    public class ScaleBitmap {

    // ------------------------------------------------
    //
    // ---o public static methods
    //
    // ------------------------------------------------

    /**
    * draw
    */
    public static function draw(bitmap : BitmapData, // bitmap data source
    graphic:Graphics, // graphic to draw
    width:Number, // draw width
    height:Number, // draw height
    inner : Rectangle, // inner rectangle (relative to 0,0)
    outer : Rectangle=null):void{ // outer rectangle (relative to 0,0)

    // some useful local vars
    var x:int, y:int, i:int, j: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 = bitmap.width;
    var sh : int = bitmap.height;

    // outer null ?
    if (outer==null){
    outer = new Rectangle(0,0,sw,sh);
    }


    // matrix creation
    var mat : Matrix = new Matrix();

    // pre-calculate widths
    var widths : Array=[ inner.left,
    inner.width,
    sw - inner.right];

    // pre-calculate heights
    var heights : Array=[ inner.top,
    inner.height,
    sh - inner.bottom];

    // resized part
    var resize : Point=new Point( width - widths[0] - widths[2],
    height - heights[0] - heights[2]);

    // let's draw
    for (x=0;x<3;x++){

    // original width
    wid = widths[x];

    // draw width
    dwid = x==1 ? resize.x : widths[x];


    // original & draw offset
    dy=oy=0;

    for (y=0;y<3;y++){

    // original & draw height
    hei = heights[y];
    dhei = y==1 ? resize.y : heights[y];

    if (dwid > 0 && dhei>0){

    // some matrix computation
    mat.a=dwid/wid;
    mat.d=dhei/hei;
    mat.tx=-ox*mat.a + dx;
    mat.ty=-oy*mat.d + dy;
    mat.translate(-outer.left,-outer.top);

    // draw the cell
    graphic.beginBitmapFill(bitmap,mat,false,true);
    graphic.drawRect(dx - outer.left, dy - outer.top, dwid, dhei);
    graphic.endFill();
    }


    // offset incrementation
    oy += hei;
    dy += dhei;
    }

    // offset incrementation
    ox += wid;
    dx += dwid;
    }
    }
    }
    }
    144 changes: 144 additions & 0 deletions ScaleBitmapSprite.as
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,144 @@
    /**
    *
    *
    * ScaleBitmapSprite
    *
    * @author Didier Brun - http://www.bytearray.org
    * @version 1.0
    *
    */

    package org.bytearray.display {
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.geom.Rectangle;

    public class ScaleBitmapSprite extends Sprite {


    // ------------------------------------------------
    //
    // ---o properties
    //
    // ------------------------------------------------

    private var _width : Number;
    private var _height : Number;
    private var _inner : Rectangle;
    private var _outer : Rectangle;
    private var _bitmapData : BitmapData;
    private var _outerWidth : Number;
    private var _outerHeight : Number;
    private var _minWidth : Number;
    private var _minHeight : Number;

    // ------------------------------------------------
    //
    // ---o constructor
    //
    // ------------------------------------------------

    function ScaleBitmapSprite( bitmap : BitmapData,
    inner : Rectangle,
    outer : Rectangle=null) {

    _inner = inner;
    _outer = outer;
    _bitmapData = bitmap;

    if (_outer!=null){
    _width = outer.width;
    _height = outer.height;
    _outerWidth = bitmap.width - outer.width;
    _outerHeight = bitmap.height - outer.height;
    } else {
    _width = inner.width;
    _height = inner.height;
    _outerWidth = 0;
    _outerHeight = 0;
    }

    _minWidth = bitmap.width - inner.width - _outerWidth;
    _minHeight = bitmap.height - inner.height - _outerHeight;

    draw();
    }

    // ------------------------------------------------
    //
    // ---o public methods
    //
    // ------------------------------------------------

    /**
    * draw
    */
    public function draw():void {

    graphics.clear();

    ScaleBitmap.draw( _bitmapData,
    graphics,
    Math.floor(_width + _outerWidth),
    Math.floor(_height + _outerHeight),
    _inner,
    _outer);
    }


    // ------------------------------------------------
    //
    // ---o public methods
    //
    // ------------------------------------------------

    /**
    * get width
    */
    override public function get width():Number{
    return _width;
    }

    /**
    * set width
    */
    override public function set width(w:Number):void {
    _width=Math.max(w,_minWidth);
    draw();
    }

    /**
    * get height
    */
    override public function get height():Number{
    return _height;
    }

    /**
    * set height
    */
    override public function set height(h:Number):void {
    _height=Math.max(h, _minHeight);
    draw();
    }

    /**
    * get bitmapData
    */
    public function get bitmapData() : BitmapData{
    return _bitmapData;
    }

    /**
    * set bitmapData
    */
    public function set bitmapData(b : BitmapData) : void {

    _bitmapData=b;
    draw();

    }

    }
    }