RileyE RileyE - 6 days ago 6
Android Question

Scaled Bitmap maintaining aspect ratio

I would like to scale a

Bitmap
to a runtime dependant width and height, where the aspect ratio is maintained and the
Bitmap
fills the entire width and centers the image vertically, either cropping the excess or filling in the gap with 0 alpha pixels.

I'm currently redrawing the bitmap myself by creating a
Bitmap
of all 0 alpha pixels and drawing the image
Bitmap
on top of it, scaling to the exact specified width and maintaining the aspect ratio, however, it ends up losing/screwing up the pixel data.

Here is how I'm doing it:

Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888);
float originalWidth = originalImage.getWidth(), originalHeight = originalImage.getHeight();
Canvas canvas = new Canvas(background);
float scale = width/originalWidth;
float xTranslation = 0.0f, yTranslation = (height - originalHeight * scale)/2.0f;
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
canvas.drawBitmap(originalImage, transformation, null);
return background;


Is there a library out there or some better code that can do this better? I would like the image to look as crisp as possible, but I knew that my function wouldn't provide a great result.

I know I could have the image stay fine by using integer scaling, instead of float scaling, but I need the width to be 100% filled.

Also, I know about an
ImageView
's
Gravity.CENTER_CROP
capability, however, that also uses integer scaling, so it cuts off the width of the image when it shouldn't.

Answer

What about this:

Bitmap background = Bitmap.createBitmap((int)width, (int)height, Config.ARGB_8888);

float originalWidth = originalImage.getWidth(); 
float originalHeight = originalImage.getHeight();

Canvas canvas = new Canvas(background);

float scale = width / originalWidth;

float xTranslation = 0.0f;
float yTranslation = (height - originalHeight * scale) / 2.0f;

Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);

Paint paint = new Paint();
paint.setFilterBitmap(true);

canvas.drawBitmap(originalImage, transformation, paint);

return background;

I added a paint to filter the scaled bitmap.

Comments