Skip navigation

Tag Archives: Flex 3

Image caching with Flex 3

As always I will start with my examples because I know most people want to see a demo before reading about it. Both of these examples are identical except for one line of code which flags image caching on or off. I have added so you can see the memory usage as you load more images. You will notice that when using the example with image caching you can load hundreds of images with little memory impact and it is much faster than the example with out caching. Also if you do not believe open up your task manager and view the memory usage of your browser to confirm that ImageCache is really working.
View source is enabled so you can see whats going on.

App NOT using cache
App using cache

I have seen several Flex 3 image caching solutions out on the web but most of them seemed to subclass SWFLoader or Image. In my opinion the Image class should know nothing about caching, it should just know about displaying the image. Why add extra functionality to the Image class? Why not have something else manage the caching? So I created ImageCache which is a utility class that handles caching images which can then be used as the source for any Image component.

The reason I like this approach is that it leaves the Image class alone and if you want to cache something you do not need to swap all the Images in your app with some subclass. You only need to change the way you set the Images source property.

I thought the browser cached images?

You may think that you don’t need to cache your images in Flex because your browser is already doing that. While it is true that your browser is caching the images that your Flex app requests it probably works a little different then you think. For example the first time you load an image you might notice that it takes a second, but if you load that same url again it shows up right away. This must mean that it is using a cached version of the image right? Well thats partly correct your browser is giving you a cached version of the image BUT, your Flex app is creating a whole new instance of that image data. So by default you get a speed gain with your browsers cache but what you are not getting is any memory gains. Each time you load that image your Flex app’s memory usage will go up by the size of that image. This is because each Image component keeps a separate BitmapData for its own use. In some cases this is good but most of the time it is not necessary and can be wasteful.

If we cache the images in the app it self we can achieve even faster loading speeds because we do not even need to ask the browser for the image. Second and even better, we can reuse the same image over and over with almost no memory overhead. This is done by sharing the same BitmapData between multiple Image components.

How it works

ImageCache works by keeping a mapping between URL and BitmapData. When you use ImageCache to cache an image it will load the image and then store the BitmapData for that image. Then when you want to set an Image component’s source to that image ImageCache will create a new Bitmap using a reference to the stored BitmapData. This means that there is almost no memory overhead and the image will load almost instantly because we are just referencing the BitmapData instead of creating a whole new copy of it. One thing to note is that because of the BitmapData sharing if you change the underlaying BitmapData of one of the Images all of the Images referencing that BitmapData will also change. This may or may not be good for you depending on how your app works.

ImageCache currently has 4 public methods:

public function setImageSource(image:Image, source:Object):void
public function cacheImage(source:Object):void
public function flushImage(source:Object):void
public function loadIntoCache(source:Object):void

The setImageSource method allows you to set an Image’s source using the cache. If the url is not cached already this method will cache the image and set the Image component’s source. If the image is already cached it will just set the Image component’s source.

Next the cacheImage method will simply cache an image with out setting any component’s source. This is useful for pre-caching images so they can be used later on with out having to load them.

If you want to flush an image from the cache you can use the flushImage method to do so. This method removes an image from the cache meaning that the next time it is requested it will ask the browser.

Lastly the flush method will clear all images in the cache.

When you use the setImageSource method you do not have to worry about timing or whether or not the image has been cached yet because ImageCache already accounts for that. It will keep a list of Image components that want a certain source and once it has finished caching it will go back and set it on all the Images that were waiting.

One more thing. I require Image components but that could easily be swapped out for SWFLoader or whatever class you wanted. This is just a quick example to show the benefits of using caching in your app. The same techniques could also be used to cache any type of file your app might be loading .swf, .pdf, .xml and so on.

Maintaining transparency with BitmapData

This took me a while to figure out but it was really simple once I read the docs.

BitmapData.draw example

You want to use the BitmapData class’s draw method to get a “copy” of some thing in ActionScript. You simply create a new BitmapData and then use the draw method and all is well right? Not quite. If you are using the draw method on something that has transparentcy, like a .png image, you might notice that now all of your transparent pixels are white. This is not a bug it is simply because you have not properly set up your BitmapData. If you take a look at the docs BitmapData’s constructor takes a 4th optional parameter called fillColor. The fillColor is a unsigned int that defaults to 0xFFFFFFFF if you do not pass anything in. At first glance you might look at that default value and think hey there are two extra F’s in there, but that is indeed a correct value. The fillColor param is a 32-bit ARGB color value. This mean the first two F’s specify the alpha, then the next two the red, then green, and then blue. This color is used to fill the bitmaps image area and because it is set to 0xFFFFFFFF (solid white) by default you create an all white BitmapData.

Then when you call draw you are drawing on top of the already white BitmapData with the image that has transparency. It is no wonder all the transparent pixels turned white you are really just seeing through the image to the white background. Don’t worry this is very easy to fix just change the default fill color to something transparent like so:

var transBMD:BitmapData = new BitmapData(w, h, true, 0x00ffffff);

You can see here we set the fillColor to 0x00ffffff or white with alpha of 0, this means the BitmapData will have no background color and when we do the draw we will keep our transparency.

Here is a more complete example of the code.

var transBMD:BitmapData = new BitmapData(origImage.content.width * 0.5
    origImage.content.height * 0.5,
    true, 0x00ffffff); //Note the first two 0's mean the alpha level is 0

var trans:Matrix = new Matrix(); //a transform matrix
trans.scale(0.5, 0.5); //scale the image
transBMD.draw(origImage, trans); //draw original image but scale it
var img:Image = new Image();
img.source = new Bitmap(transBMD); //This image will be 50% smaller and still have the transparency

I should also note that if you use BitmapData.copyPixels it will preserve the transparency and is much faster than using draw, but does not allow for stretching, rotating, or adding color effects. If you are not going to be doing any of those copyPixels is a better choice because of it’s speed.

Here is a link to a live Flex example with view source enabled that shows how this all works.
BitmapData.draw example

Flex 3 runtime loading with RSLs and Modules

Before I start I know a lot of people just want to see demos so here are links to the two demos I have. They can also be found later on in this post.

RSLs on demand

I wanted to load code into my Flex application during runtime instead of compiling it into my app. I was not quite sure how to go about doing this and many google searches revealed nothing. At this point I was not even sure it was possible but after much research and playing around I came up with what I think is a pretty decent way of doing this and decided that I should share it with everyone. I created a couple sample applications to show how this can work and enabled the source so you can see exactly what is going on. There are two examples one that makes use of Modules (my personal choice) and one that uses RSLs. Read more about both below.

Why not just compile everything into your app?

Recently I was working on a project that was basically made up of a number of smaller components. Users would be able to select and add components to it during runtime. Also new components would be released periodically and I did not want to have to rebuild the application every time a new component was released. The app would be able to get information about all of the components from a database so the application would know that these new components existed. I just needed to come up with a good way to load them. I considered several options such as compiling each component into its own swf. I could then load each swf as I needed it. This method seemed kind of dirty plus I wanted a way to load actual classes and be able to instantiate them my self. I decided to figure out a way that I could load code into the application during run time similar to how a dll can be loaded during a programs execution. This would give me a couple of benefits:

  • The ability to load and use classes not built into the main application at compile time
  • Separation of code into different swfs
  • Make code changes with out recompiling the entire application
  • Faster application load times
  • Save bandwidth by loading only the code you need when you need it
  • Provides an easy way to add extend and add to an application

Runtime-shared Libraries

Read about using RSL’s

Now you might be thinking “Haven’t you ever heard of runtime-shared libraries?” Indeed I have heard of runtime-shared libraries and used them numerous times. In fact my first attempt to this runtime loading was with RSLs and it worked alright but it was not quite what i wanted. See my example below.

Usually runtime-shared libraries are used to tell Flash Player to cache certain libraries so they do not need to be loaded everytime your app is loaded: They are also used so that multiple apps can share common code. This works by telling Flex which libraries you want to load as runtime-shared libraries. Then your application gets compiled with out them and you compile them as runtime-shared libraries with mxmlc. The libraries are then loaded the first time you run the app and cached by the Flash Player (if they are signed). The next time the application loads it will not need to reload those libraries as they are cached. This make the first application load a little slower but subsequent loads can be much faster, especially when you cache the Flex frame work. Even if your RSLs are not signed this still allows you to make code changes once and not have to recompile all of your apps just the one RSL that changed.

That being said it is possible to load runtime-shared libraries on demand during runtime, not just at the very beginning. The classes they contain can then be used just as if they where at compiled into the application.

This is the first method I tried to use but soon found it difficult to compile the components because of different dependencies for each one. I put together a couple prototypes using RSLs and ran into some problems: Most of the time it was missing dependences. For example one of the components was a Button but I had problems getting the halo.skins package into the RSL and thus caused runtime errors. I imagine most of these were caused by the way I was building the RSLs but I decided to see if there was an easier way.

Loading RSLs on the fly example (View Source Enabled)

RSLs on demand

To load an RSL at runtime you just have to use a Loader with a LoaderContext to load the RSL into your main applications ApplicationDomain. I have enabled view source on this example also.

Modules and the ModuleManager

Read about using Modules

After doing a little more searching I remembered a little thing called Module. Modules are specifically meant to be loaded at runtime and they are super easy to build. They also can be optimized similarly to how you can choose what packages you build into an RSLs. After reading the documentation I decided that Modules might the way to go.

Most of the time Modules are used to load complex forms or other large components at runtime to help cut down applications initial load. Using the mxml ModuleLoader you are able to load and unload these Modules and then use them just like any other UIComponent. You can also use the ModuleManager class to load a Module if you require a little more control. The ModuleManager returns an IModuleInfo which can be used to create and instance of the Module.

Close but not quite what I was after

This was great but I wanted to be able to load any type of code at runtime not just a Module, which is a UIComponent. I wanted to be able to load and use class references so I could do instantiation my self. I had an idea that would still use Modules but the Modules that I loaded would really act as a factory. This factory could then return what ever it was I really wanted. This would allow me to load anything: It could be a UIComponent, a Class, or any other type of object, not just a Module.

What I came up with

I ended up building a class called DynamicFactory which has a public method createFromModule. This method loads a module that implements IFactoryModule and then returns what ever it was that you really wanted. This method takes 2 parameters type (the type to create) and moduleUrl (the location of the Module to use). This setup is very flexible because I can return both instances and classes from the Module. Also having multiple components in one Module gives some performance increases over having a separate Module for each component. This is because once a Module is loaded subsequent creations from it do not have to reload the Module.

DynamicFactory example (View Source Enabled)


In this example the Module urls and the types that they can create are hard coded into the application. In a real situation these values would come from a database or some other source. This would allow the application to use new components as they are created. Also note that once a module is loaded creating another component from the same module does not cause the module to be loaded again. The ModuleManager is smart enough to know which Modules are loaded.

Final Thoughts

I would guess that most of the time, most people could satisfy their needs using just the Module and ModuleBase Classes. I had some specific needs and that is why I created the DynamicFactory Class but I would first recommend trying to use the stuff that Flex already provides.