Creating an image asset library

Creating an image asset library

Posted 27 August 2009 by Russ in Adobe Flex.

Ever had those perplexing errors where Flex Builder refuses to compile image assets into your project even though you’ve instantiated them? Create an asset library and you’ll never have that problem again…

The problem

When you compile your Flex projects there will come a time when you realise that some classes just aren’t getting compiled into the bin-release folder, perhaps because you have some conditional ActionScript code that instantiates a class according to some logic and the Flex compiler assumes that your class isn’t required.

This is an annoying quirk of the compiler and there are a common workaround is to instantiate a ‘dummy’ instance of one of these uncompiled classes to ensure that it gets included. I prefer to avoid this by creating an external asset library that compiles into its own SWC library file as follows…

Creating a Library project

A Flex Library project can be created in the same way as any other project: just choose Flex Library Project in the New menu instead of Flex Project.

Creating a new Flex Library project

At first glance nothing has changed other than the icon in the Flex Navigator view (shown below) but the benefit of this approach will become apparent very shortly.

Creating a new Flex Library project

Create a Class

First we need to create at least one class. For this example I’ve chosen to use the excellent FamFamFam Silk Icon library – a collection of 700+ 16px x 16px images that are used for many online interfaces. For this article we’ll add all the icons from this library to our Flex Library Project and then expose two of them for use in an external application.

Import the assets

This is easy – just download the icon library, extract it and drag all of the images into the Library Project. For my example these live at /assets/images/famfamfam/silkicons/. They can live anywhere but this structure makes it easy it easy to add assets from other sources to our library.

Exposing the assets

For this example we just need two of the icons and to expose these we create a new class called IconLibrary (mine’s in the package com.russback). This is a straight-forward bindable class that has a public static constant of type Class for each of the assets we want to expose:

package com.russback
{
	/**
	 * Class containing constants for each icon image available for use in the application
	 */
	[Bindable]
	public final class IconLibrary
	{

		/**
		 * Displays the accept icon from the FamFamFam Silk Icons library
		 */
		[Embed(source="assets/images/famfamfam/silkicons/accept.png")]
		public static const ACCEPT:Class;

		/**
		 * Displays the bomb icon from the FamFamFam Silk Icons library
		 */
		[Embed(source="assets/images/famfamfam/silkicons/bomb.png")]
		public static const BOMB:Class;

		/**
		 * Constructor
		 */
		public function IconLibrary()
		{
		}

	}
}

Compiling the Library

Now all we need to do is compile the Library and this is where the benefit of using this approach kicks in. If you right-click on the Flex Library Project in the Flex Navigator view and choose Properties, you’ll get your compiler options. Click on Flex Library Build Path and you’ll see a view with a button bar (Classes, Assets, Source path, Library path). In the Classes view you can select which classes you want the compiler to compile into the library. The beauty of this is that you take control – the compiler will compile whatever you choose regardless of whether you’ve used the class anywhere so we go ahead and make sure our IconLibrary class gets included.

Choosing classes to compile

Next, click on the Assets button and make sure that all the images in the library are included. We could just include the two assets we’re exposing and that would create a very small SWC file but the great thing about SWC files is that only the classes and assets it references will get included in any release build (which paradoxically caused the initial problem we’re solving…). So as we only have two references to these assets (in our IconLibrary class) we know don’t need to worry about our SWC footprint.

Choosing assets to compile

I should at this point credit Ronald Ferguson for this as he has already walked this path and his free library works great. It has constants for every icon in the library; however this creates a large SWC file and with 700+ icons in the library, it’s hard to justify this footprint. The trade off is that every time you want to use an icon that’s not referenced in the IconLibrary class we need to go back to it and add a new constant.

I’ve used the Silk Icon library as an example here but you could easily extend this Library to include other image sets as required; the approach is exactly the same, just make sure that any new class you add to the Library project gets compiled by following the steps above.

Linking to the library in an external application

So we now have a library that by default will be compiled to a SWC file in the bin directory of our Library Project. To use that SWC library file in any other Flex Project we just need to reference it in each project as follows

  1. Right-click on the project in the Flex Navigator view and choose Properties
  2. Click on Flex Build Path and then hit the Library path button
  3. Click the Add SWC… button and navigate to the SWC file your in your Library Project’s bin directory and hit Open
  4. You should now have your SWC referenced as the screenshot below shows

External SWC lib file referenced

Using the Library

Using the Library couldn’t be any easier: We simply bind the source property of an Image class to the constant in the Library that we want to use:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical"
	width="553"
	height="200"
	viewSourceURL="srcview/index.html"
	>
	<mx:Script>
		<![CDATA[
			import com.russback.IconLibrary;
		]]>
	</mx:Script>

	<mx:HBox>
		<mx:Image source="{IconLibrary.BOMB}" />
		<mx:Text text="Add images inline?" />
	</mx:HBox>

	<mx:HBox>
		<mx:Image source="{IconLibrary.ACCEPT}" />
		<mx:Text text="Use an external image library?" />
	</mx:HBox>

</mx:Application>

You can download and edit the source code for the example application and also the example Library, You can also right-click on the demo below and choose View Source to see how it all fits together.

You need Flash Player 10 to view this content. You can download this for free from the Adobe website. If you’re using a feed reader you could try loading this post in your web browser.

Using this method might seem like a pain at first but it keeps your code clean, your assets in one manageable location
, and you can say goodbye to those compiler problems.

One last note on compiler errors

Using this method you may find you get a compiler warning for each constant when you compile the Library, particularly if you compile documentation using Ant and asdoc.

Ant build warning

There is nothing to worry about here; the compiler is simply telling you that you haven’t created an instance of the constant. If you want to get rid of these completely, you can add an additional line to the build.xml file used by Ant and your compiler will run happily silent:

<arg line="-warn-const-not-initialized=false" />

Ant build successful

6 Responses to “Creating an image asset library”

  1. Frederic

    28. Sep, 2009

    Nice post.

    I thought about doing the exact same thing but how do you reference these icons from a CSS file?

    Reply to this comment
    • Russ

      29. Sep, 2009

      I haven’t used this approach in external CSS files as the application design hasn’t called for that. This approach has been most useful for inline images or when setting styles using the setStyle() method in an ActionScript class. So that may leave you with just declaring inline style references on an element, or at best, declaring a in your MXML.

      Reply to this comment
  2. Fabien Nicollet

    28. Oct, 2009

    Excellent article with clear explanations,thanks. I translated this article in french here:

    http://www.flex-tutorial.fr/2009/10/26/creer-un-projet-flexlibrary-pour-les-assets-icones-elements-graphiques/

    Reply to this comment
  3. Devin

    29. Oct, 2009

    I’d like to add a library of 1000 images – do I really have to repeat this 1000 times??? Because that would really suck!

    [Embed(source="assets/images/IMAGENAME.png")]
    public static const BOMB:Class;

    Any way to just look at a directory and create a class for each image in it dynamically – name of the class being the fileName without the extension. Do you know how to do that?

    Reply to this comment
    • Russ

      02. Nov, 2009

      I know exactly what you mean! I’d write something in PHP or similar that recursively worked through a directory structure and created a text file with the ActionScript in it. Then that can just be copied over to the Flex project.

      Perhaps not an ideal solution but it works well enough.

      Reply to this comment
  4. Rolandas

    27. Feb, 2010

    great post. ty.

    Reply to this comment

Leave a Reply