Reputation: 8930
I would like to display an image as the screen background and since I am having difficulties with image view's scale_type
in the xml, I am doing the computations with image ratio and screen dimensions in a function, nothing too complicated
public static Bitmap BitmapToView(Bitmap img, View v) {
int imgWidth = img.getWidth();
int imgHeight = img.getHeight();
int bckWidth = v.getWidth();
int bckHeight = v.getHeight();
float ratio1 = (float) bckWidth / imgWidth;
float ratio2 = (float) bckHeight / imgHeight;
float maxRatio = Math.max(ratio1, ratio2);
int newHeight = Math.max((int) (imgHeight * maxRatio), bckHeight);
int newWidth = Math.max((int) Math.ceil(imgWidth * maxRatio), bckWidth);
Bitmap tmp_image = Bitmap.createScaledBitmap(img, newWidth, newHeight, true);
Bitmap ret_image = Bitmap.createBitmap(tmp_image, Math.abs(newWidth - bckWidth)/2, Math.abs(newHeight - bckHeight)/2, bckWidth, bckHeight);
tmp_image.recycle();
return ret_image;
}
Options options = new Options();
options.inJustDecodeBounds = false;
Bitmap img = BitmapFactory.decodeFile(imgFilePath, options);
Bitmap newImage = BitmapToView(img, findViewById(R.id.myRelativeLayout);
// RelariveLayout takes up the whole screen ; failing on Samsung Galaxy S4
findViewById(R.id.myRelativeLayout).setBackground(new BitmapDrawable(newimage));
And sometimes I get an out of memory exception
I have tried to use .recycle()
here and there but then I get "Canvas: trying to use a recycled bitmap"
Any idea ? Thanks
Upvotes: 0
Views: 195
Reputation: 49807
You said you already tried recycle()
? But I see you use the same variable for the scaled and not scaled image, have you tried this:
Bitmap image = BitmapFactory.decodeFile("/.../path", options);
...
Bitmap scaledImage = Bitmap.createScaledBitmap(image, newWidth, newHeight, true);
image.recycle(); // <-- Use a new variable for the scaled image so you can recycle the not scaled one
If that doesn't help you please post more of your code and give us more information about what you are trying to do. Otherwise it will be difficult to help you.
EDIT:
This code should crop the small image before scaling it up and should therefore significantly reduce how much memory you use.
Unfortunately I can't test it right now but I'm pretty sure it should work as expected. If there are any problems feel free to ask.
public static Bitmap BitmapToView(Bitmap img, View v) {
double imgWidth = img.getWidth();
double imgHeight = img.getHeight();
double viewWidth = v.getWidth();
double viewHeight = v.getHeight();
// Crop image to required aspect ratio
double imgRatio = imgWidth / imgHeight;
double viewRatio = viewWidth / viewHeight;
double cropWidth;
double cropHeight;
if (imgRatio > viewRatio) {
cropWidth = viewRatio * imgHeight;
cropHeight = imgHeight;
} else {
cropHeight = imgWidth / viewRatio;
cropWidth = imgWidth;
}
int cropX = (int) (imgWidth / 2.0 - cropWidth / 2.0);
int cropY = (int) (imgHeight / 2.0 - cropHeight / 2.0);
Bitmap croppedBitmap = Bitmap.createBitmap(img, cropX, cropY, (int)cropWidth, (int)cropHeight);
img.recycle();
// Scale image to fill view
Bitmap finalBitmap = Bitmap.createScaledBitmap(croppedBitmap, (int)viewWidth, (int)viewHeight, true);
croppedBitmap.recycle();
return finalBitmap;
}
Upvotes: 1