Home » AS3, Strange/Bugs, flash, usefull

getBounds() on DisplayObject not functioning properly

26 January 2010 3 Comments

Well in fact, it is… or is it not ? depends on how you see it.

The trouble

If using masks or objects that have their “visible” property on true but “alpha” at 0.0, it is taken into account into the calculation of the bounding rectangle. Even objects that are outside of the masked area are added to it.

The solution(s)

  1. During my search, I found a post from David Barlia: http://studio.barliesque.com/blog/2008/10/the-trouble-with-getbounds/. He uses a custom technique to approximately calculate the bounding area of a DisplayObject.
  2. In that same post, someone proposed to use BitmapData to do so. Its code didn’t suit my needs so I wrote my own that takes into account the fact that the 0,0 coordinates in a DisplayObject is not always the upper left corner of it.
public static function getRealBounds(displayObject:DisplayObject):Rectangle
{
var bounds:Rectangle;
var boundsDispO:Rectangle = displayObject.getBounds( displayObject );

var bitmapData:BitmapData = new BitmapData( int( boundsDispO.width + 0.5 ), int( boundsDispO.height + 0.5 ), true, 0 );

var matrix:Matrix = new Matrix();
matrix.translate( -boundsDispO.x, -boundsDispO.y);

bitmapData.draw( displayObject, matrix, new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) );

bounds = bitmapData.getColorBoundsRect( 0xFF000000, 0xFF000000 );
bounds.x += boundsDispO.x;
bounds.y += boundsDispO.y;

bitmapData.dispose();
return bounds;
}

Which one is best ?

Well, if you’re looking for speed, then you might want to take a look at David’s proposal. But if you’re looking for precision, mine is better.

How does it work ?

For those of you who want to understand how it works, here you go:

  • first, I get the bounds of the DisplayObject with the getBounds() function. Why ? because I need to know how big my BitmapData has to be and also because I need to know the upper left coordinates of my DisplayObject .
  • Then I simply translate my Matrix object with those coordinates to draw the DisplayObject into my BitmapData so I have the whole picture of it and not just a picture starting at 0, 0 of my DisplayObject.
  • Notice the ColorTransform object passed to the draw() function. This will colorize in red everything that is not transparent on the BitmapData.
  • This, in order to get a precise bounding rectangle calculated with this color, thanks to the getColorBoundsRect() function of BitmapData.
  • Then I add the x and y coordinates of the “original” bounding rectangle to the final one.

There might be some bugs but it works pretty well for me at the moment.
Tkx to David and his readers.

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • E-mail this story to a friend!
  • LinkedIn
  • TwitThis

3 Comments »

  • Adrian Parr said:

    Hi Thomas,

    Thanks for sharing this code. It is really handy. I have used it to to do bitmapData.draw() on a masked movieclip. Which I was having problems with until I found your post.

    I have posted my code to Snipplr …

    http://snipplr.com/view/32341/as3-bitmapdatadraw-with-masked-displayobject/

    Cheers,

    Adrian

  • Thomas (author) said:

    cool

  • Bill said:

    All I have to say is you are a life saver, this works perfectly. getBounds wasnt working for me in my situation and was always off by serveral pixels sometimes, where this works every time.

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

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

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.

Security Code: