web-dev-qa-db-fra.com

Quel est le meilleur moyen de redimensionner un objet BitmapData?

Disons que j'ai un BitmapData de 600x600 et que je veux le réduire à 100x100.

34
Iain

Cela marche:

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);
68
Iain
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 est une interface pour DisplayObject et BitmapData. 

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

19
Carlo

Avec lissage:

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;
}

La méthode draw accepte IBitmapDrawable qui est une interface pour DisplayObject et BitmapData. 

10
sodah

Sans écrire le code moi-même. Pour ce faire, je voudrais créer un nouvel objet BitmapData de la taille souhaitée, puis utiliser la méthode bitmap.draw pour copier le plus grand dans le plus petit. La méthode bitmap.draw accepte également un argument de matrice que vous pouvez utiliser pour mettre à l'échelle lorsque vous copiez.

1
James Hay

Le problème de l’utilisation de la mise à l’échelle matricielle est qu’il ne fait pas d’anticrénelage ni de lissage - c’est probablement acceptable si vous êtes certain de ne jamais effectuer une réduction de l’échelle, mais une méthode plus générale utiliserait la classe Image pour effectuer le redimensionnement. En AS3, cela ne serait jamais ajouté à la liste d’affichage, il ne serait donc utilisé que "hors écran". Quelque chose comme ça (avec vos données bitmap en tant que "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;

Vous pouvez ensuite utiliser "scaledBitmapData" à la place de "sourceBitmapData" pour tout faire avec.

0
MicroAngelo

Voici une variante de ce qui précède qui prend en charge le zoom, l’étirement et la boîte aux lettres. Il ne peut pas fournir le support de coupure. 

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;
}
0
1.21 gigawatts