views:

347

answers:

2

Hi!

I'm trying to replicate this function from the Allegro graphics library:

void stretch_blit(BITMAP *source, BITMAP *dest, int source_x, 
                  int source_y, int source_width, int source_height, 
                  int dest_x, dest_y, dest_width, dest_height); 

http://www.allegro.cc/manual/api/blitting-and-sprites/stretch_blit

This is somewhat difficult in Flash, because of the overlapping functionality between the Rectangle and Matrix arguments of AS3's BitmapData.draw() method.

This is what I have so far. It only works most of the time, and is incredibly inefficient (due to having to sample pixels twice).

function stretch_blit(src:BitmapData, dest:BitmapData, source_x:int, source_y:int, 
   source_width:int, source_height:int, dest_x:int, dest_y:int, 
   dest_width:int, dest_height:int):void {
     var tmp:BitmapData = new BitmapData(dest_width, dest_height, true);
     var scalex:Number = dest_width/source_width;
     var scaley:Number = dest_height/source_height;
     var matrix:Matrix = new Matrix();
     var matrix2:Matrix = new Matrix();
     matrix.scale(scalex, scaley);
     matrix.translate(source_x, -source_y);
     tmp.draw(src, matrix, null, null, new Rectangle(0, 0, dest_width, dest_height));
     matrix2.translate(dest_x-source_x, dest_y-source_y);
     dest.draw(tmp, matrix2);
}

Is there a better way to do this?

+1  A: 

I thought the 5th parameter to draw was the source rect, so do you mean source_width and source_height?

Anyways, try this:

function stretch_blit(src:BitmapData, dest:BitmapData, source_x:int, source_y:int,
source_width:int, source_height:int, dest_x:int, dest_y:int, dest_width:int, dest_height:int):void {
     var scalex:Number = dest_width/source_width;
     var scaley:Number = dest_height/source_height;
     var matrix:Matrix = new Matrix();
     matrix.scale(scalex, scaley);
     matrix.translate(dest_x, dest_y);
     dest.draw(src, matrix, null, null, new Rectangle(source_x, -source_y, source_width, source_height));
}

And if you are using the inverted y axis (the flash style y axis) remove the - from -source_y

jonathanasdf
A: 

Thanks, but nothing is drawn when I try using it. I think that it has something to do with the clipRect's x and y position being offset by the Matrix' position. If you use this instead:

    function stretch_blit(src:BitmapData, dest:BitmapData, source_x:int, source_y:int,
    source_width:int, source_height:int, dest_x:int, dest_y:int, dest_width:int, dest_height:int):void {
         var scalex:Number = dest_width/source_width;
         var scaley:Number = dest_height/source_height;
         var matrix:Matrix = new Matrix();
         matrix.scale(scalex, scaley);
         matrix.translate(dest_x, dest_y);
         dest.draw(src, matrix, null, null, new Rectangle(source_x+dest_x, source_y+dest_y, source_width, source_height));
    }

Then the correct clip of the source bitmap is drawn, at the right X value in 'dest', but at the wrong Y value!

jcw