Image control

Adobe Flex supports several image formats, including GIF, JPEG, PNG, SVG, and SWF files. You can import these images into your applications by using the Image control. The Image control is part of the MX component set. There is no Spark equivalent.

The Spark component set does include a BitmapImage class. This class, however, is only meant for use in FXG components or skin classes, and not for importing images into a main application. Furthermore, you can only use embedded images with the BitmapImage class; the BitmapImage class does not support runtime loading of images.

Note: Flex also includes the SWFLoader control for loading Flex applications. You typically use the Image control for loading static graphic files and SWF files, and use the SWFLoader control for loading Flex applications. The Image control is also designed to be used in custom item renderers and item editors. For more information on the SWFLoader control, see SWFLoader control.

About importing images

Flex supports importing GIF, JPEG, PNG, and SWF files at run time, and embedding GIF, JPEG, PNG, SVG, and SWF at compile time. The method you choose depends on the file types of your images and your application parameters.

Embedded images load immediately, because they are already part of the Flex SWF file. However, they add to the size of your application and slow down the application initialization process. Embedded images also require you to recompile your applications whenever your image files change. For an overview of resource embedding, see Embedding assets.

The alternative to embedding a resource is to load the resource at run time. You can load a resource from the local file system in which the SWF file runs, or you can access a remote resource, typically though an HTTP request over a network. These images are independent of your Flex application, so you can change them without causing a recompile operation as long as the names of the modified images remain the same. The referenced images add no additional overhead to an application’s initial loading time. However, you might experience a delay when you use the images and load them into Adobe Flash Player or AIR.

A SWF file can access one type of external resource only, either local or over a network; it cannot access both types. You determine the type of access allowed by the SWF file by using the use-network flag when you compile your application. When use-network flag is set to false, you can access resources in the local file system, but not over the network. The default value is true, which allows you to access resources over the network, but not in the local file system.

For more information on the use-network flag, see Flex compilers.

When you load images at run time, you should be aware of the security restrictions of Flash Player or AIR. For example, you can reference an image by using a URL, but the default security settings only permit Flex applications to access resources stored on the same domain as your application. To access images on other servers, you must use a crossdomain.xml file.

For more information on application security, see Security.

SVG drawing restrictions

You should be aware of the following restrictions when working with SVG files in Flex:

  • You can only embed an SVG file in an application; you cannot load one at run time

  • SMIL and animation are not supported

  • Masking and filters are not supported

  • Pattern Fill and some advanced Gradients are not supported

  • Interactivity and scripting is not supported

  • SVG text is rendered as nonsearchable and nonselectable SWF shape outlines, meaning it is not rendered as native text in Flash Player or AIR

Controlling image importing with the Image control

The Image control supports the following actions when you import an image:

Specifying the image path

The value of the source property of an Image control specifies a relative or absolute path, or URL to the imported image file. If the value is relative, it is relative to the directory that contains the file that uses the tag.

The source property has the following forms:

  1. source="@Embed(source='relativeOrAbsolutePath')"

    The referenced image is packaged within the generated SWF file at compile-time when Flex creates the SWF file for your application. You can embed GIF, JPEG, PNG, SVG, and SWF files. When you embed an image, the value of the source property must be a relative or absolute path to a file on your local file system; it cannot be a URL.

    The following example embeds a JPEG image into a Flex application:

    <?xml version="1.0"?>
    <!-- controls\image\ImageSimpleEmbed.mxml -->
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx">
    
        <mx:Image id="loader1" source="@Embed(source='logo.jpg')"/> 
    </s:Application>

    The executing SWF file for the previous example is shown below:

    In this example, the size of the image is the default size of the image file.

  2. source="relativeOrAbsolutePathOrURL"

    Flex loads the referenced image file at run time; it is not packaged as part of the generated SWF file. You can only reference GIF, JPEG, PNG, and SWF files. When use-network flag is set to false, you can access resources in the local file system, but not over the network. The default value is true, which allows you to access resources over the network, but not in the local file system.

    The following example accesses a JPEG image at run time:

    <?xml version="1.0"?>
    <!-- controls\image\ImageSimple.mxml -->
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx">
     
        <mx:Image id="loader1" source='logo.jpg'/> 
    </s:Application>

    The executing SWF file for the previous example is shown below:

    Because you did not use @Embed in the source property, Flex loads the image at run time.

In many applications, you create a directory to hold your application images. Commonly, that directory is a subdirectory of your main application directory. The source property supports relative paths to images, which lets you specify the location of an image file relative to your application directory.

The following example stores all images in an assets subdirectory of the application directory:

<?xml version="1.0"?>
<!-- controls\image\ImageSimpleAssetsDir.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <mx:Image id="loader1" source="@Embed(source='assets/logo.jpg')"/> 
</s:Application>

The executing SWF file for the previous example is shown below:

The following example uses a relative path to reference an image in an assets directory at the same level as the application’s root directory:

<?xml version="1.0"?>
<!-- controls\image\ImageSimpleAssetsDirTop.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <mx:Image id="loader1" source="@Embed(source='../assets/logo.jpg')"/> 
</s:Application>

The executing SWF file for the previous example is shown below:

You can also reference an image by using a URL, but the default security settings only permit Flex applications to access resources stored on the same domain as your application. To access images on other servers, you must use a crossdomain.xml file.

The following example shows how to reference an image by using a URL:

<?xml version="1.0"?>
<!-- controls\image\ImageSimpleAssetsURL.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <mx:Image id="image1" 
        source="http://localhost:8100/flex/assets/logo.jpg"/> 
</s:Application>
Note: You can use relative URLs for images hosted on the same web server as the Flex application, but you must load these images over the Internet rather than access them locally.

Using an image multiple times

You can use the same image multiple times in your application by using the normal image import syntax each time. Flex only loads the image once, and then references the loaded image as many times as necessary.

Sizing an image

Flex sets the height and width of an imported image to the height and width settings in the image file. By default, Flex does not resize the image.

To set an explicit height or width for an imported image, set its height and width properties of the Image control. Setting the height or width property prevents the parent from resizing it. The scaleContent property has a default value of true; therefore, Flex scales the image as it resizes it to fit the specified height and width. The aspect ratio is maintained by default, so the image may not completely fill the designated space. Set the scaleContent property to false to disable scaling. Set the maintainAspectRatio property to false to allow an image to fill all available space regardless of its dimensions. For more information about image aspect ratios, see below.

To let Flex resize the image as part of laying out your application, set the height and width properties to a percentage value. Flex attempts to resize components with percentage values for these properties to the specified percentage of their parent container. You can also use the maxHeight and maxWidth and minHeight and minWidth properties to limit resizing. For more information on resizing, see Introduction to containers.

One common use for resizing an image is to create image thumbnails. In the following example, the image has an original height and width of 100 by 100 pixels. By specifying a height and width of 20 by 20 pixels, you create a thumbnail of the image.

<?xml version="1.0"?>
<!-- controls\image\ImageSimpleThumbnail.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <mx:Image id="image1" 
        source="@Embed(source='logo.jpg')" 
        width="20" height="20"/>
    <mx:Image id="image2" 
        source="@Embed(source='logo.jpg')"/>
</s:Application>

The executing SWF file for the previous example is shown below:

Maintaining aspect ratio when sizing

The aspect ratio of an image is the ratio of its width to its height. For example, a standard NTSC television set uses an aspect ratio of 4:3, and an HDTV set uses an aspect ratio of 16:9. A computer monitor with a resolution of 640 by 480 pixels also has an aspect ratio of 4:3. A square has an aspect ratio of 1:1.

All images have an inherent aspect ratio. When you use the height and width properties of the Image control to resize an image, by default Flex preserves the aspect ratio of the image so that it does not appear distorted.

By preserving the aspect ratio of the image, Flex might not draw the image to fill the entire height and width specified for the <mx:Image> tag. For example, if your original image is a square 100 by 100 pixels, which means it has an aspect ratio of 1:1, and you use the following statement to load the image:

<mx:Image source="myImage.jpg" height="200" width="200"/>

The image increases to four times its original size and fills the entire 200 x 200 pixel area.

The following example sets the height and width of the same image to 150 by 200 pixels, an aspect ratio of 3:4:

<mx:Image source="myImage.jpg" height="150" width="200"/>

In this example, you do not specify a square area for the resized image. Flex maintains the aspect ratio of an image by default; therefore, Flex sizes the image to 150 by 150 pixels, the largest possible image that maintains the aspect ratio and conforms to the size constraints. The other 50 by 150 pixels remain empty. However, the <mx:Image> tag reserves the empty pixels and makes them unavailable to other controls and layout elements.

You can use a Resize effect to change the width and height of an image in response to a trigger. As part of configuring the Resize effect, you specify a new height and width for the image. Flex maintains the aspect ratio of the image by default, so it resizes the image as much as possible to conform to the new size, while maintaining the aspect ratio. For example, place your mouse pointer over the image in this example to enlarge it, and then move the mouse off the image to shrink it to its original size:

<?xml version="1.0"?>
<!-- controls\image\ImageResize.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Script>
        <![CDATA[
            import mx.effects.Resize;
        ]]>
    </fx:Script>
    <fx:Declarations>
        <mx:Resize id="resizeBig" 
            widthFrom="22" widthTo="44" 
            heightFrom="27" heightTo="54"/>
        <mx:Resize id="resizeSmall" 
            widthFrom="44" widthTo="22" 
            heightFrom="54" heightTo="27"/>
    </fx:Declarations>

    <mx:Image width="22" height="27"
        source="@Embed('logo.jpg')" 
        rollOverEffect="{resizeBig}" 
        rollOutEffect="{resizeSmall}"/>
        
</s:Application>

The executing SWF file for the previous example is shown below:

For more information on the Resize effect, see Introduction to effects.

If you do not want to preserve the aspect ratio when you resize an image, you can set the maintainAspectRatio property to false. By default, maintainAspectRatio is set to true to enable the preservation of the aspect ratio.

The following example resizes the logo to the exact values of the height and width properties without regard for its aspect ratio:

<?xml version="1.0"?>
<!-- controls\image\ImageResizeMaintainAR.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <mx:Image id="image1" 
        source="@Embed('logo.jpg')" 
        width="250" height="100" 
        maintainAspectRatio="false"/> 
</s:Application>

The executing SWF file for the previous example is shown below:

By choosing not to maintain the aspect ratio, you allow for the possibility of a distorted image. For example, the Adobe logo is 136 by 47 pixels by default. In the following example, it is distorted because the aspect ratio is not maintained when the image is resized:

Setting visibility

The visible property of the Image control lets you load an image but render it invisible. By default, the image is visible. To make an image invisible, set the visible property to false. The following example loads an image into the solid-bordered VBox. The image is not visible until the user selects the checkbox:

<?xml version="1.0"?>
<!-- controls\image\ImageVisible.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <mx:VBox id="vbox0" borderStyle="solid">
        <mx:Image id="img0" 
            visible="{cb1.selected}" 
            source="@Embed(source='logo.jpg')"
        />
    </mx:VBox>
    <s:CheckBox id="cb1" 
        label="Show image"
        x="30"/>
</s:Application>

The executing SWF file for the previous example is shown below:

The VBox container still allocates space for the image when it lays out its children. Thus, the VBox is the same size as the image file and, if your application contained a Button control after the <mx:Image> tag, the button would appear in the same location as if the image were visible.

If you want to make the image invisible, and have its parent container ignore the image when sizing and positioning its other children, set the includeInLayout property of the Image control to false. By default, the includeInLayout property is true, so that even when the image is invisible, the container sizes and positions it as if it were visible.

Often, you use the visible property to mark all images invisible, except one image. For example, assume that you have an area of your application dedicated to showing one of three possible images based on some user action. You set the visible property set to true for only one of the possible images; you set the visible property set to false for all other images, which makes them invisible.

You can use ActionScript to set image properties. In the following example, when the user clicks the button, the action sets the visible property of the image to true to make it appear:

<?xml version="1.0"?>
<!-- controls\image\ImageAS.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <fx:Script>
        <![CDATA[
            private function toggleImage():void {
                if (image1.visible) 
                    image1.visible=false
                else 
                    image1.visible=true;
            }
        ]]>
    </fx:Script>
    <mx:VBox id="vbox0">
        <mx:Image id="image1" 
            visible="false" 
            source="@Embed(source='logo.jpg')"/> 
        <s:Button id="myButton" 
            label="Toggle Image" click="toggleImage();"/>
    </mx:VBox>
</s:Application>

The executing SWF file for the previous example is shown below:

If you set the visible property, you can control when images are loaded. By allocating space but making images invisible when a page loads, you ensure that any slower performance occurs during the initialization stage when users expect it, rather than as they interact with the application and perform actions that require the image. By setting the visible property, you can also prevent resizing and relayout within your application at seemingly random intervals.

Techniques for using the Image control

Often in a product catalog, when a user clicks an item, the catalog displays an image of the item. One strategy for building a catalog is to load the catalog images into your application, but make them all invisible. When a user selects a product, you make that image visible.

However, this strategy requires that you add an Image control for all the images in your catalog and load the images, even if they are invisible, when the application starts. The resulting SWF file would be unnecessarily large, because it would contain all the images and the start-up time would be negatively affected by loading invisible images.

A better strategy is to dynamically load the images from your server, as necessary. In this way, your SWF file stays small, because it does not have to contain invisible images, and your start-up time improves.

As part of its implementation, the ActionScript class that defines the <mx:Image> tag is a subclass of the SWFLoader class. After creating an image, you can use the properties and methods of the SWFLoader control with your image, including the load() method, which loads an image file dynamically.

Note: The load() method of the SWFLoader control only works with GIF, JPEG, PNG, and SWF files; you cannot use it to load SVG files.

The following example uses the load() method to replace a small image with a large image when the user clicks a button:

<?xml version="1.0"?>
<!-- controls\image\ImageLoad.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    creationComplete="toggleImage()">

  <fx:Script>
    <![CDATA[
        private var imageSmall:String = "logo.jpg";
        private var imageLarge:String = "logowithtext.jpg";     
    
      private function toggleImage():void {
        // Runtime location of the images is the same folder
        // as this MXML file.
        if (image1.source == imageSmall) {
            image1.load(imageLarge);            
        } else {
            image1.load(imageSmall);
        }
      }
    ]]>
  </fx:Script>

  <mx:VBox id="vbox0">
      <s:Button id="myButton" 
          label="Toggle Image" 
          click="toggleImage();"
      />
      <mx:Image id="image1"/> 
  </mx:VBox>
</s:Application>

The executing SWF file for the previous example is shown below:

Notice in this example that the application accesses the images in the local file system; they are not embedded or accessed by URL. Therefore, you have to compile this application with the use-network flag set to false.

The container that holds the image does not adjust the layout of its children when you call the load() method. Therefore, you typically replace one image with another image of the same size. If the new image is significantly larger than the original, it can overlay other components in the container.

You can make the selection of the replacement image based on a user action in your application. For example, you might want to load an image based on a user selection in a list box or data grid.

In the next example, you use the index number of the selected item in a data grid to determine the image to load. In this example, images are named 1.jpg, 2.jpg, 3.jpg, and so on, corresponding to items in the grid.

// Retrieve the image associated with the item selected in the grid 
private function getImage():void { 
    var cartGrid:DataGrid = dgrid; 
    var imageSource:String = 'images/' + cartGrid.getSelectedIndex() + '.jpg'; 
    image1.load(imageSource); 
}

In this example, the images are stored in the images directory. The complete path to an image is the directory name, the index number, and the file suffix .jpg.

You register this function as the event listener for a change event in the data grid, as follows:

<mx:DataGrid id="dgrid" height="200" width="350" change="getImage();"/>

When a user changes the currently selected item in the data grid, Flex calls the getImage() function to update the displayed image.

You could modify this example to use information about the selected item to determine the image to load, rather than by using the selected item’s index. For example, the grid could contain a list of objects, where each object has a property that contains the image name associated with it.

In addition to the load() method, you can also access other properties of the SWFLoader control, including percentLoaded. The percentLoaded property is particularly useful because it lets you to display a progress bar so users know that the application did not become unresponsive. For a complete list of the SWFLoader properties and methods, see the ActionScript 3.0 Reference for the Adobe Flash Platform.