Reputation: 2381
im having problems with high resolution images.
Im using nodpi-drawable folder for 1280x720 images, and using this code to scale it.
public static Drawable scaleDrawable(Drawable d, int width, Activity cxt)
{
BitmapDrawable bd = (BitmapDrawable)d;
double oldWidth = bd.getBitmap().getWidth();
double scaleFactor = width / oldWidth;
int newHeight = (int) (d.getIntrinsicHeight() * scaleFactor);
int newWidth = (int) (oldWidth * scaleFactor);
Drawable drawable = new BitmapDrawable(cxt.getResources(),MainScreen.getResizedBitmap(bd.getBitmap(),newHeight,newWidth));
BitmapDrawable bd2 = (BitmapDrawable)drawable;
return drawable;
}
public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
I use that code to scale images to screen witdh so if the screen is 320x480 the image will scale to 320 and keep proportions, i dont care if image go out of screen from bottom.
All its working fine, but when trying in a xhdpi device specifically a Samsung Galaxy Note 2 with a screen of exactly 720x1280.
It crash with Out Of Memory Exception in the line:
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
I cant understand why, the image should be scaled from 720 to 720 but my code must be really bad optimized or something.
I havent tried on a 1080x1920 device but it seems it will crash too.
Someone can see something bad when looking at the code?
Upvotes: 2
Views: 2941
Reputation: 17580
use this method to resize your bitmap-
Bitmap bm=decodeSampledBitmapFromPath(src, reqWidth, reqHeight);
use this Defination-
public Bitmap decodeSampledBitmapFromPath(String path, int reqWidth,
int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(path, options);
return bmp;
}
}
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
If you are using resource then replace method with BitmapFactory's decodeResource method..
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
....
.....
return BitmapFactory.decodeResource(res, resId, options);
}
Upvotes: 7
Reputation: 109
You should use the utility class BitmapFactory for image-processing-operations. Also use BitmapFactory.Options to adjust the input/output sizes of the bitmaps. After a bitmap is not needed anymore, you should free the related memory.
Upvotes: 0