Bad image quality after resizing/scaling bitmap

Cbas picture Cbas · Jan 27, 2011 · Viewed 99k times · Source

I'm writing a card game and need my cards to be different sizes in different circumstances. I am storing my images as bitmaps so that they can be quickly drawn and redrawn (for animation).

My problem is that no matter how I try and scale my images (whether through a matrix.postScale, a matrix.preScale, or a createScaledBitmap function) they always come out pixelated and blurry. I know that its the scaling thats causing the problem because the images look perfect when drawn without resizing.

I have worked through every solution described in these two threads:
android quality of the images resized in runtime
quality problems when resizing an image at runtime

but still haven't gotten anywhere.

I store my bitmaps (into a hashmap) with this code:

cardImages = new HashMap<Byte, Bitmap>();
cardImages.put(GameUtil.hearts_ace, BitmapFactory.decodeResource(r, R.drawable.hearts_ace));

and draw them with this method (in a Card class):

public void drawCard(Canvas c)
{
    //retrieve the cards image (if it doesn't already have one)
    if (image == null)
        image = Bitmap.createScaledBitmap(GameUtil.cardImages.get(ID), 
            (int)(GameUtil.standardCardSize.X*scale), (int)(GameUtil.standardCardSize.Y*scale), false);

        //this code (non-scaled) looks perfect
        //image = GameUtil.cardImages.get(ID);

    matrix.reset();
    matrix.setTranslate(position.X, position.Y);

    //These methods make it look worse
    //matrix.preScale(1.3f, 1.3f);
    //matrix.postScale(1.3f, 1.3f);

    //This code makes absolutely no difference
    Paint drawPaint = new Paint();
    drawPaint.setAntiAlias(false);
    drawPaint.setFilterBitmap(false);
    drawPaint.setDither(true);

    c.drawBitmap(image, matrix, drawPaint);
}

Any insight would be greatly appreciated. Thanks

Answer

le huynh picture le huynh · Sep 19, 2011

Use createScaledBitmap will make your image looks very bad. I've met this problem and I've resolved it. Below code will fix the problem:

public Bitmap BITMAP_RESIZER(Bitmap bitmap,int newWidth,int newHeight) {    
    Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);

    float ratioX = newWidth / (float) bitmap.getWidth();
    float ratioY = newHeight / (float) bitmap.getHeight();
    float middleX = newWidth / 2.0f;
    float middleY = newHeight / 2.0f;

    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bitmap, middleX - bitmap.getWidth() / 2, middleY - bitmap.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

    return scaledBitmap;

    }