How to resize an image with ActionScript (update)

imageResizeLanczos

If you need to resize an image on client side, I mean real bitmapData resize (not just showing scaled), feel free to use ImageResizer class. This class takes bitmapData of source image, new width and height and resize method (defined by ResizeMath class), and returns new bitmapData of resized image.

Update: It seems that bitmapData.draw() method uses bilinear algorithm when scaling via Matrix. Bilinear algorithm gives you fine results when downscaling no more than 2 times (400px -> 200px). So, I added bilinearIterative() method into ImageResizer class that creates resized bitmapData by multiple steps achieving much smoother results!

Source of sk.yoz.image.ImageResizer class:

package sk.yoz.image
{
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Point;
    
    import sk.yoz.math.ResizeMath;
    
    public class ImageResizer extends Object
    {
        public function ImageResizer()
        {
        }
        
        public static function bilinear(source:BitmapData, width:uint, 
            height:uint, method:String, allowEnlarging:Boolean=true):BitmapData
        {
            var scale:Point = ResizeMath.scale(
                new Point(source.width, source.height), 
                new Point(width, height), method, allowEnlarging);
            var result:BitmapData = new BitmapData(width, height, true, 0x0);
            var matrix:Matrix = new Matrix();
            matrix.scale(scale.x, scale.y);
            matrix.tx = (width - source.width * scale.x) / 2;
            matrix.ty = (height - source.height * scale.y) / 2;
            result.draw(source, matrix, null, null, null, true);
            return result;
        }
        
        public static function bilinearIterative(source:BitmapData, width:uint, 
            height:uint, method:String, allowEnlarging:Boolean = true,
            iterationMultiplier:Number = 2):BitmapData
        {
            var w:uint = source.width;
            var h:uint = source.height;
            var result:BitmapData;
            while(!result || w != width || h != height)
            {
                w = source.width > width 
                    ? Math.max(w / iterationMultiplier, width) 
                    : Math.min(w * iterationMultiplier, width);
                h = source.height > height 
                    ? Math.max(h / iterationMultiplier, height) 
                    : Math.min(h * iterationMultiplier, height);
                result = bilinear(result || source, w, h, method, 
                    allowEnlarging);
            }
            return result;
        }
    }
}

Usage is pretty simple. You also gonna need sk.yoz.math.ResizeMath class.

var result:BitmapData = ImageResizer.bilinearIterative(sourceBitmapData, 100, 100,
    ResizeMath.METHOD_PAN_AND_SCAN);

Alternatives & Benchmarking

There are also another possible methods to resize/resample images. Read more about bilinear resampling and bicubic resampling methods using pixel bender. I benchamrked all methods and here are the results:

source    | result  | ImageResizer | ImageResizer        | Bilinear PB | Bicubic PB
          |         | bilinear()   | bilinearIterative() |             |
4x4       | 200x200 |         0 ms |                3 ms |       16 ms |      31 ms
946x946   | 200x200 |         0 ms |                7 ms |       16 ms |      47 ms
1200x1200 | 200x200 |         0 ms |                9 ms |       32 ms |      47 ms

Comparing ImageResizer.bilinear() method with bilinear and bicubic pixel bender resizing. Even though, all methods are pretty fast, the results are far from beeing as good as Lanczos algorithm results (e.g. used in IrfanView):

resizingMethodBenchmark

Comparing ImageResizer.bilinear(), ImageResizer.bilinearIterative() and Lanczos algorithm:

imageResizeLanczos

If you are looking for transformation between BitmapData, Bitmap, ByteArray, read this article.

Update November 10, 2010: Lanczos Resampling With ActionScript

11 comments so far

  1. […] you won’t be able to get nice results when downscaling more than 2 times. Inspired by ImageResizer class I have also created SmoothImage Class. This object extends mx.Image and uses […]

  2. Frank March 6, 2010 00:37

    You saved my life ;-)

    Since days I was looking for a solution to scale large bitmapData to small ones. Thank you very much!

  3. Marcelo Casé April 10, 2010 00:04

    Really amazing! Your solution fits perfect in a navigation I’m developping for a website. As soon as I publish it I will let you know!
    Thanks!

  4. […] Après avoir cherché pas mal de temps, une classe permettant de faire du resize d’image j’en ai trouvé une pas mal du tout à utiliser dans vos projets! Je cherchais une classe pouvant redimensionner mes images proportionnelement évidemment avec une qualité exemplaire. C’est chose faite et ça se passe ici ====>http://blog.yoz.sk/2010/01/how-to-resize-an-image-with-actionscript/ […]

  5. SonicE November 4, 2010 10:41

    YOU ARE MY HERO !!!!!! Looking for this since 3 months!!! Thank you!

  6. […] How to resize an image with ActionScript […]

  7. gitar December 23, 2010 10:40

    thans for the sample code

  8. Andrew January 27, 2011 09:31

    Nice work, glad to have found this – saves me a bunch of time rolling my own, thanks! :)

  9. Uros July 31, 2011 21:03

    Thank you very much!

  10. Ivan December 13, 2011 23:56

    Thanks a lot! So quick resize a image 4000×4000 to 200×200 ~ 46ms

  11. YopSolo January 5, 2012 23:31

    really usefull, thx !

Leave a comment

Please be polite and on topic. Your e-mail will never be published.