AS 3 | Cloning Png image data

断了今生、忘了曾经 提交于 2019-12-24 09:58:03

问题


I need to clone .png image data loaded from server in AS3, so that I am not required to load same data again and again from server.

After a search on cloning image data in AS3 I was able to find following code over internet

clone = new Bitmap(Bitmap(this._loader.content).bitmapData.clone() )

By using this code I am able to clone bitmap data but the problem which I am facing is that my png background is transparent. If I typecast loaded png data to bitmap my icons background becomes white.

Any help would be appreciated.


Hi Laurent & TheDarkIn1978, Thanks a lot for quick revert back and your valuable suggestions,

Let me put complete picture in front of you guys,

I am trying to load icons from server which has to be displayed at several places in same movieclip.

To display image data I have created a movieclip in which I directly add loaded content as its child by calling addChild() function.

Now the problem occurs when I try to add same image data on another movieclip as its chil, new parent of data gets set and this image is removed from previously added content. So at the end this icon is displayed only at one position on movieclip (due to fact that each child can have a single parent).

Therefore I thought to clone image data and display it on screen, when ever Image from server is loaded I call following function to save image data in local,

   private var _bmapData : BitmapData;
    _bmapData = new BitmapData(_loader.width, _loader.height );
    _bmapData.draw( this );
    isImageLoaded=true;'

Now whereever I have to show this data , I use to call following code to clone png data

var dup : Image = new Image();
 dup.addChild(new Bitmap(_bmapData.clone()));
 return dup;

What I beleive transpareny is only supported in png format, not in bitmap or jpeg, therefore my background icons are getting white.

Kindly help as I am stucked and not able to understand my next steps.


回答1:


The code you posted in your update is nearly there, you just need a couple more parameters in your BitmapData call to get the transparency working:

private var _bmapData : BitmapData;
_bmapData = new BitmapData(_loader.width, _loader.height, true, 0);
_bmapData.draw( this );

Note the true, 0 I've added. true is setting transparency to true, and the 0 saying no background color should be added by Flash.

Edit Since this has garnered some debate, I will elaborate on why this is necessary (and why some of my comments were slightly incorrect).

First here's the documentation for the BitmapData constructor. If you fancy reading that, then the rest of this answer will be pointless, because for the most part I'm just going to repeat it.

So, the BitmapData constructor takes 4 parameters, width, height, transparency and background color. Let's ignore width and height, and move straight onto transparency, which by default is set to true. The catch is that in order for the BitmapData object to actually implement a transparent background, it's background color must be set to black.

transparent:Boolean (default = true) — Specifies whether the bitmap image supports per-pixel transparency. The default value is true (transparent). To create a fully transparent bitmap, set the value of the transparent parameter to true and the value of the fillColor parameter to 0x00000000 (or to 0).

So amazingly, even though BitmapData is set to transparent by default, the background color defaults to 0xFFFFFFFF, which prevents the transparent flag from having any effect. This means that in order to have a properly thansparent background to a BitmapData object, you must declare a pure black background color.

Finally, if you still want proof, run this and enjoy:

package {

    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.events.Event;

    public class Main extends MovieClip
    {
        private var bg          :Shape;

        private var bitmap1     :Bitmap;
        private var bitmap2     :Bitmap;

        public function Main():void
        {
            stage ? init() : addEventListener(Event.ADDED_TO_STAGE,init);
        }

        private function init(event:Event = null):void
        {
            if(event) removeEventListener(Event.ADDED_TO_STAGE,init);

            drawBackground();
            drawBitmaps();
        }

        private function drawBackground():void
        {
            //create a light colored background
            bg = addChild(new Shape()) as Shape;
            bg.graphics.beginFill(0xD0D0D0);
            bg.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
            bg.graphics.endFill();
        }

        private function drawBitmaps():void
        {
            //create a bitmap in the documented fashion
            var bmd1:BitmapData = new BitmapData(200,200,true);
            bitmap1 = addChild(new Bitmap(bmd1)) as Bitmap;
            //this time, give a background color
            var bmd2:BitmapData = new BitmapData(200,200,true,0x000000);
            bitmap2 = addChild(new Bitmap(bmd2)) as Bitmap;
            bitmap2.x = 200;
        }
    }
}



回答2:


The code you posted should also copy the alpha channel. How do you display the Bitmap?

Edit: I think there must be some other issues with your code or the way you display the BitmapData. I just tried the following and it works fine:

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener("complete", function(event) {
    // Cache the bitmap data
    var bmpData = event.currentTarget.content.bitmapData.clone();
    // Create a new Bitmap and display the bitmap data
    var bmp = new Bitmap(bmpData);
    addChild(bmp); // The PNG is displayed with transparency
});
loader.load(new URLRequest("http://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png"));

Maybe try to alter your code so that it works like this example?




回答3:


alternatively, you can cache your loaded Bitmap within a static object. so instead of repeatedly loading the same data, this approach allows you to check if the Bitmap had been previously loaded and will simply retrieve the cached Bitmap based on the data's URL (for example) instead of reloading the Bitmap.

public static var cachedImages:Object = new Object();

...

private function checkCache(imageURL:String):void
{
     if (cachedImages[imageURL])
        showImage(cachedImages[imageURL]);
        else
        loadImage(imageURL);

}

...

private function loadImageCompleteHandler(evt:Event):void
{
    cachedImages[imageURLProperty] = evt.currentTarget.content;
}


来源:https://stackoverflow.com/questions/6977514/as-3-cloning-png-image-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!