Actionscript: resizing bitmapdata with smoothing

2019-08-25 09:13发布

问题:

var bd:BitmapData=new BitmapData(file.width,file.height);
bd.setPixels(new Rectangle(0,0,file.width,file.height),file.raw);

var scale_x_percents:Number = (w / bd.width);
var scale_y_percents:Number = (h / bd.height);
if(!stretch) {
    if(bd.width*scale_y_percents>=w) {
        scale_x_percents=scale_y_percents;
    }
    else if(bd.height*scale_x_percents>=h) {
        scale_y_percents=scale_x_percents;
    }
}
var matrix:Matrix = new Matrix();
matrix.scale(scale_x_percents,scale_y_percents);

var resizedBd:BitmapData = new BitmapData(Math.floor(bd.width*scale_x_percents), Math.floor(bd.height*scale_y_percents), true, 0x000000);
resizedBd.draw(bd, matrix, null, null, null, true); // true is smoothing option, it will blur sharpened pixels

Having problem with images resizing. Looks like smoothing is not working or something is missing in the code. Maybe Matrix should have something more?

Original image:

http://imageshack.us/a/img28/4784/dc7f2ec4b0f3323cdc4e01e.jpg

and it's result:

http://imageshack.us/a/img855/4784/dc7f2ec4b0f3323cdc4e01e.jpg

I can link a bunch of others images. Some strange pixel disposition exist. Can it be fixed somehow?

I have tested jpeg quality 100% and stage.quality='best', but none of them give the required quality outcome.

回答1:

It seems that your problem is "nearest" sampling mode when drawing a BitmapData over a BitmapData. Perhaps the following might help:

var sh:Shape=new Shape();
sh.graphics.beginBitmapFill(bd,matrix,false,true);
sh.graphics.lineStyle(0,0,0); // no lines border this shape
sh.graphics.drawRect(0,0,resizedBD.width,resizedBD.height);
sh.graphics.endFill();
resizedBD.draw(sh); // or with smoothing on

Using Flash's native graphics renderer will most likely perform at least a bilinear interpolation on a drawn bitmap, which seemingly is your desired result. Also, stage.quality applies if that shape is added to stage (BTW, you can use the shape to display an uploaded pic, then draw over a BitmapData in order to save.) But, this might not work - I can't test this right now.