Scaling bitmaps for each resolution - android

Is there any method that gets the phones resolution (or dp) and scales bitmaps accordingly? I have all my images in xhdpi folder and at the moment they do not scale the way they should.
I want an efficiant and memory-friendly method that can do the scaling automatically. If not, what is the next best thing? completely new area for me. So any tutorial-link is also appriciated.
this is what I use to load bitmaps atm:
public Bitmap loadBitmap(int resourceID) {
Options options = new BitmapFactory.Options();
options.inScaled = true;
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap tempBmp = null;
try {
tempBmp = BitmapFactory.decodeResource(getResources(), resourceID,
options);
} catch (OutOfMemoryError e) {
} catch (Error e) {
}
return tempBmp;
}

If you wanna scale bitmap for each phone resolution, you should know phone screen size, scale ratio.
This code will return width (w) & height (h) of screen.
DisplayMetrics dMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dMetrics);
float density = dMetrics.density;
int w = Math.round(dMetrics.widthPixels / density);
int h = Math.round(dMetrics.heightPixels / density);
activity is instance of Activity which would you like to get screen size.
You have to remember that: When your device is in landscape orientation, w > h. When it in portrait orientation w < h.
So from width & height you can detect your device is in what orientation.
Example:
From w & h of device and ratio (which you want to scale) you can calculate new bitmap size to scale it.
public 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;
}

Related

How to resize image without loosing image content

I want to resize an image to a smaller image like thumbnail. I have used following options
Bitmap imageBitmap = Bitmap.createScaledBitmap(mBitmap, 200, 700, false);
and
ThumbnailUtils.extractThumbnail()
Both of these options cut parts of images. So they don't look good. I just want to reduce image dimensions and don't want to loose image content.
you have to try like this
public 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;
}
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(filepath,bmOptions);
//Part 1 :withcompression Sacle image 200 pixels x 700 pixels this size you can customize as per your requirement
Bitmap withCompressed = Bitmap.createScaledBitmap(bitmap,200,700,true);
If you want to resize an image without losing quality and images are from drawable/mipmap then you should try pngquant.
https://pngquant.org/

How to change bitmap height and width programmatically in android?

I want to resize the bitmap height & width into same as the user device width & height.So please help me if u know the code.Thank You !
This is my code:
Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.nature);
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
width = metrics.widthPixels;
height=metrics.heightPixels;
But it was not working
Try to use this method:
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
// GET CURRENT SIZE
int width = bm.getWidth();
int height = bm.getHeight();
// GET SCALE SIZE
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;
}
Bitmap.createScaledBitmap works great. As the document:
Creates a new bitmap, scaled from an existing bitmap, when possible. If the specified width and height are the same as the current width and height of the source bitmap, the source bitmap is returned and no new bitmap is created.

Resizing image in Android

I use the following method to resize images on Android.
public Bitmap resize(Bitmap img, int Width, int Height) {
int width = img.getWidth();
int height = img.getHeight();
int newWidth = (int) Width;
int newHeight = (int) Height;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
//matrix.postRotate(45);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(img, 0, 0, width, height, matrix, true);
return resizedBitmap;
}
It works fine on most Android devices. But on some devices the resized image is not displaying. How might I resolve this?
You may create a scaled bitmap with
Bitmap bitmap = Bitmap.createScaledBitmap(b, width, height, true);
Here, width and height you can provide according to the device's screen size for different devices, by reading screen sizes programmatically. Here is how you can read the screen size of a device programmatically.
Most likely, on "some devices" and depending on the requested width and height, there's not enough memory to create the resized bitmap. Check (in debugger) if the resizedBitmap is null when the image "is not displaying".

large bitmap size fit in to small android phones

I have a Bitmap with a size of 1024x1024.png and I need to stretch it on different device screens, I tried using this:
// given a resource, return a bitmap with a specified maximum height
public static Bitmap maxHeightResourceToBitmap(Context c, int res,
int maxHeight) {
Bitmap bmp = imageResourceToBitmap(c, res, maxHeight);
int width = bmp.getWidth();
int height = bmp.getHeight();
int newHeight = maxHeight;
int newWidth = maxHeight / 2;
// calculate the scale - in this case = 0.4f
float scaleHeight = ((float) newHeight) / height;
float scaleWidth = ((float) newWidth) / width;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap and return it
return Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true);
}
// given a resource, return a bitmap with a specified maximum height
public static Bitmap scaleWithRatio(Context c, int res,
int max) {
Bitmap bmp = imageResourceToBitmap(c, res, max);
int width = bmp.getWidth();
int height = bmp.getHeight();
// calculate the scale - in this case = 0.4f
float scaleHeight = ((float) max) / height;
float scaleWidth = ((float) max) / width;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap and return it
return Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true);
In order to stretch a bitmap on screen I would recommend to keep the bitmap as the original in memory (don't make the bitmap itself bigger in any case).
Then, when you show it on screen, usually with an ImageView, you can set the image view ScaleTypeto FIT_XY (see docs for more info). This will stretch the image on screen when drawing it to fill the entire ImageView. Also make sure your ImageView fills the entire screen by setting its LayoutParameters accordingly (fill parent for example).
The only real reason to resize bitmaps in memory is to make them smaller to save memory. This is important because Android devices have a limited heap and if you're bitmaps are too big in memory they will fill up your entire heap and you'll run into OutOfMemory errors. See this tutorial if you're running into memory problems.

Set wallpaper in Android

I have image 640*480 in sd card and i want to set it as home screen wallpaper. How Can I do this with small quality loss? With my code Wallpaper has a not good clarity. That's my code:
private void setWallpaper(String filePath) throws IOException{
if(filePath!=null){
// set options for decoding
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = false;
options.inJustDecodeBounds = true;
//get bitmap from filepath
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
//get sizes of bitmap
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//get sizes of screen and scale level
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int newWidth = display.getWidth()*2;
int newHeight = display.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
//set matrix of the scaling
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
//get new bitmap for wallpaper
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
width, height, matrix, true);
//set bitmap as wallpaper
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
wallpaperManager.clear();
wallpaperManager.setBitmap(resizedBitmap);
}
}
Any time you scale upwards you're going to suffer quality loss. What size screen are you trying to display this image one? Keep in mind the Android wallpaper dimensions are the height of the screen by 2 times the width of the screen (e.g. 800x480 screen needs a 800x960 image).
My recommendation would be to have a larger image and scale downwards. The quality loss from downsampling is far less noticeable than from upscaling. You could, if space is not an issue, include multiple sizes of the image for differing screen resolutions.

Categories

Resources