Image smoothing in Flex

The Flex Image control doesn’t expose Bitmap smoothing by default but can easily be added in through subclassing the component. Smoothing is a nice feature for removing jaggies from images that have been scaled either up or down, and in practice hasn’t caused any noticable cpu hangups to do the post processing. I’m writing up a patch to submit to the Flex Open Source initiative, but in the meantime, heres a quick and dirty hack to enable it in the Flex 2 and Flex 3 SDK.

Create a new MXML component and name it SmoothImage.mxml, then add the following code.

<?xml version="1.0" encoding="utf-8"?>
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Script>
		<![CDATA[
			import flash.display.Bitmap;
			override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void{
				super.updateDisplayList(unscaledWidth, unscaledHeight);
				if(content is Bitmap){
					var bmp:Bitmap = Bitmap(content);
					if(bmp && bmp.smoothing == false){
						bmp.smoothing = true;
					}
				}
			}
		]]>
	</mx:Script>
</mx:Image>

Now just use <local:SmoothImage source=”myimage.jpg”/> the same way you’d use a normal image component and you’re all set. This code will take care of smoothing both dynamically loaded images as well as embedded images in one simple script. It also handles broken images gracefully. Heres a quick sample showing the affects of scaling the Google logo with and without smoothing.

SmoothImage test case


And the code used to create this…

<!-- Top Images -->
<mx:Image source="{googlelogo}" width="60" height="25"/>
<mx:Image source="{googlelogo}" width="200" height="90"/>
<mx:Image source="{googlelogo}" width="400" height="180"/>

<!-- Bottom Images -->
<local:SmoothImage source="{googlelogo}" width="60" height="25"/>
<local:SmoothImage source="{googlelogo}" width="200" height="90"/>
<local:SmoothImage source="{googlelogo}" width="400" height="180"/>

9 thoughts on “Image smoothing in Flex”

  1. very cool:)

    Here is it as a class:

    package ipaper.framework
    {
    import mx.controls.Image;
    import flash.display.Bitmap;

    public class SmoothImage extends Image
    {
    override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
    {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    if(content is Bitmap)
    {
    var bmp:Bitmap = Bitmap(content);
    if(bmp && bmp.smoothing == false)
    bmp.smoothing = true;
    }
    }
    }
    }

  2. How would this work with an image that is being defined in the CSS file?

    This is great BTW — something I as a designer first, seriously need to bring my artwork into flex!

    Thanks

  3. I’ve used this approach for a while now, but just discovered that it will throw security errors if the image being loaded is coming from a different domain than the SWF. A typical error is:

    SecurityError: Error #2122: Security sandbox violation: Loader.content: [SWF_LOCATION] cannot access [IMAGE_LOCATION]. A policy file is required, but the checkPolicyFile flag was not set when this media was loaded.

    A simple solution is to wrap the conditional statement inside of a try…catch block:

    try {
    if (this.content is Bitmap) {

    var bitmap:Bitmap = Bitmap(this.content);

    if (bitmap && !bitmap.smoothing) {
    bitmap.smoothing = true;
    }

    }
    }
    catch (error:Error) {
    //Alert.show(error.toString());
    }

    This way if it runs into a security error, it will simply revert to loading the image without smoothing.

Comments are closed.