What is the best way to resize a BitmapData object?
Asked Answered
P

6

36

Say I have a BitmapData of 600x600 and I want to scale it down to 100x100.

Pickford answered 8/6, 2009 at 11:42 Comment(0)
P
68

This works:

var scale:Number = 1.0/6.0;
var matrix:Matrix = new Matrix();
matrix.scale(scale, scale);

var smallBMD:BitmapData = new BitmapData(bigBMD.width * scale, bigBMD.height * scale, true, 0x000000);
smallBMD.draw(bigBMD, matrix, null, null, null, true);

var bitmap:Bitmap = new Bitmap(smallBMD, PixelSnapping.NEVER, true);
Pickford answered 8/6, 2009 at 12:20 Comment(2)
this 0x000000 is very important, without it there is no transparencyHager
For thoose, working with StageXL dart, default Matrix has constructor Matrix.fromIdentity(). Everything else works as in this example.Merthiolate
S
18
public function drawScaled(obj:IBitmapDrawable, thumbWidth:Number, thumbHeight:Number):Bitmap {
    var m:Matrix = new Matrix();
    m.scale(WIDTH / obj.width, HEIGHT / obj.height);
    var bmp:BitmapData = new BitmapData(thumbWidth, thumbHeight, false);
    bmp.draw(obj, m);
    return new Bitmap(bmp);
}

IBitmapDrawable is an interface for DisplayObject and BitmapData.

from: http://www.nightdrops.com/2009/02/quick-reference-drawing-a-scaled-object-in-actionscript/

Smalley answered 8/6, 2009 at 18:52 Comment(3)
Not actually what I wanted, because I was starting with a bitmapdata rather than a display object. thanks though!Pickford
easily fixed by subtituting DisplayObject with BitmapData ;-)Smalley
The BitmapData.draw method accepts IBitmapData. IBitmapDrawable is an interface used by both DisplayObject and BitmapDataMicmac
M
10

With smoothing:

function BitmapScaled(source:IBitmapDrawable, thumbWidth:Number, thumbHeight:Number):BitmapData {
    var mat:Matrix = new Matrix();
    mat.scale(thumbWidth/source.width, thumbHeight/source.height);
    var bmpd_draw:BitmapData = new BitmapData(thumbWidth, thumbHeight, false);
    bmpd_draw.draw(source, mat, null, null, null, true);
    return bmpd_draw;
}

The draw method accepts IBitmapDrawable which is an interface for DisplayObject and BitmapData.

Mcalpin answered 7/7, 2011 at 9:3 Comment(0)
M
1

Without writing the code myself. The way i would approach this would be to create a new BitmapData object of the desired size and then use the bitmap.draw method to copy the large one to the small one. The bitmap.draw method also accepts a matrix argument that you can use to scale when you copy.

Melliemelliferous answered 8/6, 2009 at 12:13 Comment(0)
F
0

The problem with using matrix scaling is that it doesn't do any antialiasing or smoothing - this is probably OK if you're sure you will only ever been downscaling, but a more general method would use the Image class to do the resizing. In AS3 this would never be added to the display list, so would just be used "offscreen". Something like this (with your bitmap data as "sourceBitmapData"):

var image:Image = new Image();
image.load(new Bitmap(sourceBitmapData, PixelSnapping.NEVER, true));

var scale:uint = 100/600; // this is from your example of 600x600 => 100x100
var scaledWidth:uint = sourceBitmapData.width * scale;
var scaledHeight:uint = sourceBitmapData.height * scale;

image.content.width = scaledWidth;
image.content.height = scaledHeight;

var scaledBitmapData:BitmapData = new BitmapData(scaledWidth, scaledHeight);
scaledBitmapData.draw(image.content); 

image = null;

You can then use "scaledBitmapData" in place of "sourceBitmapData" to do whatever with.

Fourfold answered 23/6, 2009 at 2:10 Comment(4)
Where does this Image class come from? help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/… doesn't list an Image class as being part of the AS3 library.Selfsealing
Voted down as no reference to Image classDriveway
it is either help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/… or help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/…Weakly
var scale:uint --> var scale:Number, plz.Straw
M
0

Here is a variation of the above that adds support for zoom, stretch and letterbox. It may not provide the clipping support.

var newSizeBitmapData:BitmapData = resizeBitmapData(myBitmapData, newWidth, newHeight);


/**
 * Resize display object or bitmap data to a new size
 **/
public static function resizeBitmapData(bitmapDrawable:IBitmapDrawable, width:Number, height:Number, scaleMode:String="none", 
                                      smooth:Boolean = true, transparent:Boolean = true, fillColor:Number = 0x00000000):BitmapData {
    var sizedBitmapData:BitmapData;
    var matrix:Matrix;
    matrix = getSizeByScaleMode(width, height, Object(bitmapDrawable).width, Object(bitmapDrawable).height, scaleMode);
    sizedBitmapData = new BitmapData(width, height, transparent, fillColor);
    sizedBitmapData.draw(bitmapDrawable, matrix, null, null, null, smooth);

    return sizedBitmapData;
}

// Get correct scale. Inspired from code in Apache Flex (license Apache 2.0) 
public static function getSizeByScaleMode(maxWidth:int, maxHeight:int, 
                                          width:int, height:int, 
                                          scaleMode:String="letterbox",
                                          dpi:Number=NaN):Matrix {

    var aspectRatio:String = (maxWidth < maxHeight) ? "portrait" : "landscape";
    var orientation:String = aspectRatio;

    var matrix:Matrix = new Matrix();

    var scaleX:Number = 1;
    var scaleY:Number = 1;

    switch(scaleMode) {
        case "zoom":
            scaleX = Math.max( maxWidth / width, maxHeight / height);
            scaleY = scaleX;
            break;

        case "letterbox":
            scaleX = Math.min( maxWidth / width, maxHeight / height);
            scaleY = scaleX;
            break;

        case "stretch":
            scaleX = maxWidth / width;
            scaleY = maxHeight / height;
            break;
    }

    if (scaleX != 1 || scaleY != 0) {
        width *= scaleX;
        height *= scaleY;
        matrix.scale(scaleX, scaleY);
    }

    matrix.translate(-width / 2, -height / 2);

    matrix.translate(maxWidth / 2, maxHeight / 2);

    return matrix;
}
Micmac answered 21/8, 2017 at 9:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.