Skip to main content
Participating Frequently
February 19, 2007
Question

Load Images

  • February 19, 2007
  • 8 replies
  • 76802 views
Hello

Could you please assist me with such issue

I am using a Canvas object like a container for images (Image class). My application loads 500-1000 images (tiles) dynamically and then displays them. Everything works fine but the memory grows up to 300Mb.

Here is a code:


private function GetLoop(layer:String):void {
var canvas:Canvas = new Canvas();
for(var i:Number = 0; i < curFrames; i++) {
var img:Image = new Image();
img.addEventListener(Event.COMPLETE, OnImageLoaded); img.load(urlReq);
canvas.addChild(img);
}

}
    This topic has been closed for replies.

    8 replies

    odenysAuthor
    Participating Frequently
    March 6, 2007
    Thanks, buabco

    Do you know what the significant difference between Loader and URLLoader classes is?.. and what is better to use for PNG images/tiles loading?
    Known Participant
    March 6, 2007
    odenys,

    They are totally different, and they are used for totally diferent things as well. The URLLoader is meant to server side script communication, you can get a PNG from it but you'll just get the PNG data, not sure how you go from there to a display object, I don't think you can any ways, since what URLLoader provide is RAW data.

    The Loader class on the other hand is a DISPLAYOBJECT and is meant to load IMAGES and SWF files you'll use on your stage. This class does all the uncompressing of Images for you and just gives you a display object in it's "content" parameter.

    I totally recommend you the Loader class for image loading.
    odenysAuthor
    Participating Frequently
    March 6, 2007
    Hi, jpwrunyan

    Could you give any idea about such approach. I am going to load all necessary images using URLLoader and store them into the ByteArray. When the animation starts I will show necessary images from ByteArray ( using Loader.loadBytes() ). How to represent loader's content as UIComponent (e.g. to put it into canvas container) and then how to dispose this bitmap from UIComponent?
    Known Participant
    March 6, 2007
    I think I actually did this, even though I thought I was copying the bitmap, since it was more than one copy of the image on the stage.

    What I did is something like this:

    var ldr:Loader; //Lets asume this is the loader you used to load the image and the image is already loaded, I'll not add the code to actually load the image here.

    var bmp:BitmapData = new BitmapData(ldr.width, ldr.height); //Try use the real width and height here
    bmp.draw(ldr.content);

    var copy:Bitmap= new Bitmap();
    copy.bitmapData = bmp;
    odenysAuthor
    Participating Frequently
    February 22, 2007
    Thank you

    Now I better understand how the Image's object is stored into the memory.

    Thanks for the valuable advice concerning bitmap data disposing. It really helped in case of unnecessary images removing.
    Participating Frequently
    February 22, 2007
    I can't help you with your application as it is currently constructed but I may be able to shed some light as to why so much memory is being used. Flash cannot display .jpg images as such. It converts every image loaded into a bitmap. So even if you have a miniscule 15x15 gif file (approx 370 bytes) loaded into the FlashPlayer (for example, via the Image class) it gets displayed as a 15x15 bitmap with 3 or 4 bytes per pixel (depending on whether it uses the alpha channel). So now FlashPlayer is using 900 bytes of memory for your image.

    And as I think you guessed, if you use the same .gif in 4 Image class instances, each one gets loaded into its own memory location for 900 x 4 = 3,600 bytes of memory used.

    Just to give you a heads up, if you try removing the Image class after you are done with it, the bitmap data will still stay in memory causing a very serious memory leak. Although this is beyond the scope of your current application (as I understand it) it will need to be addressed by accessing the Image.content as a BitMap and then calling dispose() on the BitMap.bitmapData. I only say this now because in my experience, anytime someone is loading images dynamically in their application, they inevitably end up wanting to unload them later. So again, for future prosperity, remember to dispose your bitmap data before you remove your Image classes:

    BitMap(ImageLoader_inst.content).bitmapData.dispose();

    likewise, if you are smart(er than me) you might be able to create a bitmapData instance for shared images and pass a reference to that to Bitmaps that are being displayed in your application. Again, this will only theoretically help you if you are using the same image multiple times.

    Sorry but these are the only suggestions I can make to help cut down memory usage when dynamically loading external images--and these tips might not even apply to your current goal.
    Known Participant
    February 22, 2007
    Hi jpwrunyan,

    From reading to your explanation I ended up a little confused; are you saying that garbage collector wont destroy the image data once you dispose of the object?, lets say I have a sprite with 4 Loader classes that each loaded an image, if I remove every reference to the Sprite, and the garbage collector take care of it, and later of the loader classes since they ended up with no reference, the image data will still be eating up memory?
    Participating Frequently
    February 23, 2007
    quote:

    Originally posted by: buabco
    are you saying that garbage collector wont destroy the image data once you dispose of the object?, lets say I have a sprite with 4 Loader classes that each loaded an image, if I remove every reference to the Sprite, and the garbage collector take care of it, and later of the loader classes since they ended up with no reference, the image data will still be eating up memory?


    In essence, yes, that is what I am saying. However, I must add the caveat that I am not privy to the inner workings of the garbage collection system. What minimal knowledge I do have I picked up from gskinner.com (www.gskinner.com/blog/). Last year another forum user was having the same trouble and he ended up posting on gskinner's blog and he was able to figure out that the bitmap data had to be disposed. And he also provided some explanation as to why.

    In my case I had a component that used an Image class to load external bitmaps. I tried many different implemenations varying the following two themes:

    1) Single Image class that dynamically loaded different .jpgs
    2) Single parent class that dynamically loaded different Image classes for each .jpg

    whether changing the content of the Image, or removing the Image class entirely and creating/adding a new Image, I found that flash was holding onto the bitmap data. Since my images were 2000x1500 pixels I rapidly ran out of memory.

    However, I was not able to crash my computer the way a true memory leak should. What I found is that when I got to about 90% of my RAM, then Flash player started recycling data. My only guess is that the player decided on its own "well, I gotta get rid of something or I'm gonna crash" and therefore finally started disposing (I assume) bitmap data. However, like I said, I have no way of knowing for certain--it's just my speculation. The player could easily have been disposing of other information as well, although the sheer volume of bitmap data in memory means that, if data was chosen at random by the garbage collector, the bitmap data was most likely removed.

    This is one of those things where I really wish someone at Adobe or a Flash player engineer would enlighten the community.
    Known Participant
    February 20, 2007
    I suppose you can, but remember that when you see the file size you are looking at JPG compressed images, when flash access them it has to decompress them into memory. I guess that's the reason your memory size goes all the way to 300 MB.

    If you come to think of this having all images in one Bitmap should use more or less the same amount of memory. Still I'm not sure how flash manages its internal memory.
    odenysAuthor
    Participating Frequently
    February 20, 2007
    Thanks

    I am just trying to understand why there is so much memory being used. All 1000 tiles are ~10Mb. At the beginning the application (browser) uses ~40Mb, and after tiles loading it increases to ~300Mb. The reason is that for each image the new object is stored into the memory?

    Is it possible to use any advantages of Bitmap object? I mean to draw one bitmap (which will contain all tiles) for each canvas.
    odenysAuthor
    Participating Frequently
    February 20, 2007
    Hi, buabco

    Thank You for your quick answer

    The main idea of my application is to show animation of some layers ( Canvas which contains set of images). So, I have a set of canvases (each of them contains set of images/tiles). To do animation at first I have to load all images into the appropriate canvases (containers) an then show necessary canvas (animate).
    Known Participant
    February 20, 2007
    In that case I guess you are in trouble, my recomendation is that you consider optimizing your code. If what you are trying to achieve is a transition between canvases then you only need 2 canvases at a time, I guess you can make your code add canvases dynamically as needed instead of all at one time.

    You can still preload all the images so you'll be able to display them quickly, to do this you can use 2 or 3 image containers to download all the images, even if you destroy the image immediately after download it will stay in the browser cache, so next time you load the image in a image container it should load pretty fast. Since you are handling 90 MB of data though this can take some time.
    Known Participant
    February 19, 2007
    HI!

    you used up so much memory beacuse you have all 1000 images in memory at a time. You must load them as you need them in order to optimize this.

    Fortunatelly the TileList container is designed to do this and you should use it. If you combine it with a custom itemRenderer you'll need no code to achieve what you are looking for.