Smooth Image Resizing

Much has been written about smoothing dynamically loaded bitmaps in Flash 8. But, just in case you missed it, here's the short version: Flash 8 allows you to smooth dynamically loaded images such as JPG's at runtime by taking a snapshot of the image using BitmapData and redrawing it on to a MovieClip with smoothing applied..

It's one of those things you may never have realized you were missing until now.

At first glance, this isn't super impressive. "JPG's look fine when I load them," says the casual observer. But, the magic here is what we can now do with images that we couldn't do before. Specifically, we can rotate and scale our JPG's without all the funny artifacting and pixelation. In the past, if I wanted to view an image at multiple sizes, I needed to load separate images for each size. Now, I can simply load in one full size image and scale it down without any loss in quality. This isn't the most bandwidth friendly solution, but it is still quite useful.

Meanwhile, I've found that there are a number of tricks that go along with this process. I've encapsulated these tricks into a set of static methods...

com.bumpslide.util.ImageUtil (docs)

The functions in this class relate to two issues with loading images: Smoothing and Resizing. Smoothing is rather simple and has been documented elsewhere. The function I use to do this is ImageUtil.smoothImage(holder_mc, image_mc) where image_mc is the mc that will be smoothed and holder_mc is where the bitmap data will be rendered (usually, holder_mc==image_mc._parent).

The next trick is the resizing. Resizing an image to fit a container of a given size is not as straight-forward as you may think. After writing similar code 4 or 5 times, I finally wrapped it up in the ImageUtil class. There are two methods that do resizing. The first one (resizeRect) accepts instances of the Rectangle data type. The second one (resizeImage) operates on the image movie clip directly. The resizeImage function is not necessarily better. It simply takes care of the rectangle nonsense for you. Also, the resizeImage method will take care of applying smoothing in the process. Note: I am using the ASAP Framework Rectangle class

Actionscript:
  1. // to smooth an image that was loaded into holder_mc
  2. function onResize() {
  3.     ImageUtil.resizeImage( holder_mc, image_mc, Stage.width, Stage.height );
  4. }

Example 1: ImageUtilTest.swf
(view source)

Now, once you have an image loaded and resized, you may notice something. When resizing and preserving aspect ratio, once of the dimensions may no longer be on a whole pixel. The result of this is what I call "fringing". This is not very obvious in the example above, but when we start laying out our images with pixel perfect borders, we suddenly have a problem.

My solution to this problem is to simply stretch the image and cut off the fringe.

  1. Resize the image 2 pixels greater than the target dimensions.
  2. Offset the image location by -1, -1
  3. Mask the image to the target dimension

I have put all of this functionality in a handy class that also handles the image loading process...

com.bumpslide.ui.ResizableImage (docs)

Actionscript:
  1. var image_mc:ResizableImage;
  2.  
  3. // create resizable image
  4. image_mc = ResizableImage.create( 'image_mc', this );
  5. image_mc.addEventListener( ResizableImage.EVENT_IMAGE_LOADED, this );
  6. image_mc.load('myimage.jpg');
  7.  
  8. // update size once image is loaded
  9. function onImageLoaded() {
  10.     onResize();
  11. }
  12.    
  13. function onResize() {
  14.     image_mc.setSize( Stage.width-20, Stage.height-20)
  15. }

Example 2: ResizableImageTest.swf
(view source)

So, there it is. Smooth Image Resizing.

Photo Credit: Kemp Attwood - Miss you, man.

6 Responses to “Smooth Image Resizing”

  1. Jose Says:

    Really good job!
    Thanks for these great explanation.

  2. Gorjan Says:

    Thank you for this.

  3. gia Says:

    Good! but so complicated, maybe can using Flash JSFL
    New notepad --> paste code in this below --> save as AllowSmoothing.jsfl
    code :
    var libItems = fl.getDocumentDOM().library.items;

    for (i = 0; i Run Command and then browse for this JSFL

  4. david Says:

    gia, your JSFL didn't come through, but this code is for smoothing dynamically loaded images that need to be resized at runtime, not author time. So, I'm not sure what JSFL would do for me here. thanks, though.

  5. Pat O'Neil Says:

    I am developing a HTML/CSS/Javascript web based photo album but am not happy with either browser or php image resizing.

    Is there a way that I can use Flash high quality resizing just for the image resizing in my application?

    I don't have a copy of Flash 8, so any sample code would be greatly appreciated.

    oneilpatr-at-gmail-dot-com

  6. david Says:

    Pat, I imagine a flash component like this could be developed, but I would recommend taking another look at server-side options. I have had good luck with PHPThumb, http://phpthumb.sourceforge.net/.