1

I have this function:

    public static function cloneDpObj(target:DisplayObject):Bitmap
    {
        var duplicate:Bitmap;

        var tBitData:BitmapData = new BitmapData(target.width, target.height);
        tBitData.draw(target);
        duplicate = new Bitmap(tBitData);

        return duplicate;
    }

to clone target displayObject (MovieClip or Sprite) and return Bitmap Object.

It can get bitmap from the target object, but it seem don't get all the area of the image.

By give the width and height of target object, but the target object in design was applied by Glow Effect, so my question can we get the all view of bitmapdata from a displayobject?

Ratha Hin
  • 37
  • 1
  • 6
  • 1
    Did you try getting the dimensions using `DisplayObject.getBounds` method instead of `width` and `height`? Also, naming your function `cloneDpObj` is misleading - it doesn't clone a `DisplayObject`, at best it clones its bitmap image, although I would say it simply renders it into a new `Bitmap`. "Cloning" has a pretty well defined meaning in the context people will be reading your code in. – Armen Michaeli Aug 05 '11 at 08:24

4 Answers4

4

BitmapData.draw() takes a snapshot of a given object removing all transformations and filters applied on the stage. Resulting image shows object as it is present in your movie library.

There are two basic options when drawing display objects with transformations and/or filters.

  1. You can apply all transformations during drawing with matrix parameter for BitmapData.draw(). After drawing you can apply filters to resulting bitmap with BitmapData.applyFilter().
  2. Just draw parent container, not the object itself.

I usually choose the latter. That's pretty straightforward. There are some disadvantages: if you choose the second method, your target has to have a display list parent and you may draw unwanted content that resides in parent container. (However, these drawbacks are easily eliminated.)

// bounds and size of parent in its own coordinate space
var rect:Rectangle = target.parent.getBounds(target.parent);
var bmp:BitmapData = new BitmapData(rect.width, rect.height, true, 0);

// offset for drawing
var matrix:Matrix = new Matrix();
matrix.translate(-rect.x, -rect.y);

// Note: we are drawing parent object, not target itself: 
// this allows to save all transformations and filters of target
bmp.draw(target.parent, matrix);
Michael Antipin
  • 3,522
  • 17
  • 32
1

You need compute the area/rectangle of your DisplayObject including the area taken by the filter applied. Luckily you can do that with with built-in functionality by using the generateFilterRect() method of the BitmapData class.

Also, for other reasons, if you need the transformation of your DisplayObject applied to the BitmapData snapshot, you can pass the source DisplayObject's .transform.concatenatedMatrix as the second parameter of BitmapData's draw() method.

George Profenza
  • 50,687
  • 19
  • 144
  • 218
1

Thank you very much to all of you that take valuable time answer my question. I improved that function, but I is better, but I notice that the width of result of capture is 1pixel offset, so I decided to add 1 pixel to width of the bitmapdata, I know that is not a good practice. because I have to do that now, I don't know the issue yet. Here is how our function now:

 public static function cloneDpObj(target:DisplayObject, optWidth:Number = -1, optHeight:Number = -1):Bitmap
    {
        var duplicate:Bitmap;

        if (!target.parent) {
            var tempSprite:Sprite = new Sprite;
            tempSprite.addChild(target);
        }

        var rect:Rectangle = target.parent.getBounds(target.parent);
        var bmp:BitmapData = new BitmapData(rect.width + 1, rect.height, true, 0);

        // offset for drawing
        var matrix:Matrix = new Matrix();
        matrix.translate( -rect.x, -rect.y);

        // Note: we are drawing parent object, not target itself: 
        // this allows to save all transformations and filters of target
        bmp.draw(target.parent, matrix);

        duplicate = new Bitmap(bmp);

        return duplicate;
    } 
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Ratha Hin
  • 37
  • 1
  • 6
0

I would actually go with Nox's first option as the easier approach, and modifying your function to do it should only take one extra line of code:

public static function cloneDpObj(target:DisplayObject):Bitmap
{
    var duplicate:Bitmap;

    var tBitData:BitmapData = new BitmapData(target.width, target.height);
    tBitData.draw(target);
    duplicate = new Bitmap(tBitData);
    //add the filters
    duplicate.filters = target.filters;

    return duplicate;
}
shanethehat
  • 15,460
  • 11
  • 57
  • 87
  • Well, this is an option, but you also have to do something about the image area. Copying transformations requires using matrix and translation anyway. I think that's harder than just drawing parent object. – Michael Antipin Aug 05 '11 at 09:59
  • Thank you very much to all of you that take valuable time answer my question. I improved that function, but I is better, but I notice that the width of result of capture is 1pixel offset, so I decided to add 1 pixel to width of the bitmapdata, I know that is not a good practice. because I have to do that now, I don't know the issue yet. Here is how our function now: – Ratha Hin Aug 08 '11 at 06:33