Actionscript 3 从包含透明区域和效果区域的displayObject获取位图数据

Actionscript 3 从包含透明区域和效果区域的displayObject获取位图数据,actionscript-3,bitmapdata,Actionscript 3,Bitmapdata,我有这个功能: public static function cloneDpObj(target:DisplayObject):Bitmap { var duplicate:Bitmap; var tBitData:BitmapData = new BitmapData(target.width, target.height); tBitData.draw(target); duplicate = new Bitm

我有这个功能:

    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;
    }
克隆目标displayObject(MovieClip或Sprite)并返回位图对象

它可以从目标对象获取位图,但似乎无法获取图像的所有区域

通过给定目标对象的宽度和高度,但设计中的目标对象是通过辉光效果应用的,因此我的问题是我们可以从displayobject获取bitmapdata的所有视图吗?

bitmapdata.draw()
拍摄给定对象的快照,删除舞台上应用的所有转换和过滤器。生成的图像显示对象在电影库中的状态

使用变换和/或过滤器绘制显示对象时,有两个基本选项

  • 您可以在绘制过程中使用
    BitmapData.draw()的矩阵参数应用所有转换。绘制后,可以使用
    BitmapData.applyFilter()
    对生成的位图应用过滤器
  • 只需绘制父容器,而不是对象本身
  • 我通常选择后者。这很简单。有一些缺点:如果您选择第二种方法,您的目标必须有一个显示列表父对象,并且您可能会绘制驻留在父容器中的不需要的内容。(但是,这些缺点很容易消除。)

    BitmapData.draw()
    拍摄给定对象的快照,删除舞台上应用的所有转换和过滤器。生成的图像显示对象在电影库中的状态

    使用变换和/或过滤器绘制显示对象时,有两个基本选项

  • 您可以在绘制过程中使用
    BitmapData.draw()的矩阵参数应用所有转换。绘制后,可以使用
    BitmapData.applyFilter()
    对生成的位图应用过滤器
  • 只需绘制父容器,而不是对象本身
  • 我通常选择后者。这很简单。有一些缺点:如果您选择第二种方法,您的目标必须有一个显示列表父对象,并且您可能会绘制驻留在父容器中的不需要的内容。(但是,这些缺点很容易消除。)


    实际上,我会选择Nox的第一个选项作为更简单的方法,修改函数来实现它只需要额外的一行代码:

    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;
    }
    

    实际上,我会选择Nox的第一个选项作为更简单的方法,修改函数来实现它只需要额外的一行代码:

    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;
    }
    

    您需要计算DisplayObject的面积/矩形,包括应用的过滤器所占的面积。幸运的是,通过使用BitmapData类的方法,您可以通过内置功能实现这一点


    此外,出于其他原因,如果需要将DisplayObject的转换应用于BitmapData快照,则可以传递源DisplayObject的.transform。作为BitmapData的draw()方法的第二个参数。

    您需要计算DisplayObject的面积/矩形,包括所应用过滤器的面积。幸运的是,通过使用BitmapData类的方法,您可以通过内置功能实现这一点


    此外,出于其他原因,如果需要将DisplayObject的转换应用于BitmapData快照,则可以传递源DisplayObject的.transform。作为BitmapData的draw()方法的第二个参数。

    非常感谢各位花费宝贵时间回答我的问题。我改进了该函数,但我做得更好,但我注意到捕获结果的宽度是1像素偏移,所以我决定在bitmapdata的宽度上添加1像素,我知道这不是一个好的做法。因为我现在必须这么做,所以我还不知道问题所在。下面是我们现在的功能:

     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;
        } 
    

    非常感谢你们花宝贵时间回答我的问题。我改进了该函数,但我做得更好,但我注意到捕获结果的宽度是1像素偏移,所以我决定在bitmapdata的宽度上添加1像素,我知道这不是一个好的做法。因为我现在必须这么做,所以我还不知道问题所在。下面是我们现在的功能:

     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;
        } 
    

    您是否尝试使用
    DisplayObject.getBounds
    方法而不是
    width
    height
    获取尺寸?此外,将函数命名为
    cloneDpObj
    也会产生误导-它不会克隆
    DisplayObject
    ,充其量只能克隆其位图图像,尽管我会说它只是将其渲染为一个新的
    位图
    。“克隆”在人们阅读您的代码的上下文中有一个非常明确的含义。您是否尝试使用
    DisplayObject.getBounds
    方法而不是
    width
    height
    获取维度?此外,将函数命名为
    cloneDpObj
    也会产生误导-它不会克隆
    DisplayObject
    ,充其量只能克隆其位图图像,尽管我会说它只是将其渲染为一个新的
    位图
    。“克隆”在人们阅读你的代码的上下文中有一个很好的定义。这是一个选项,但你也必须对图像区域做一些事情。无论如何,复制变换都需要使用矩阵和转换。我认为这比仅仅绘制父对象更难。非常感谢你们所有花费宝贵时间回答我问题的人。我改进了该函数,但我做得更好,但我注意到捕获结果的宽度是1像素偏移,所以我决定在bitmapdata的宽度上添加1像素,我知道这不是一个好的做法。因为我现在必须这么做,所以我还不知道问题所在。这就是我们现在的功能:好吧,这是一个选项,但是你也必须对图像区域做一些事情。无论如何,复制变换都需要使用矩阵和转换。我认为这比仅仅绘制父对象更难。非常感谢你们所有花费宝贵时间回答我问题的人。我改进了这个功能,但是我更好,但是我