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.
Related
I am new to android. I want to reduce the size of a bitmap to 100kb exactly. I get an image from the sdcard, compress it and save it to the sdcard again with a different name into a different directory. Compression works fine (3 mb like image is compressed to around 100 kb). I trying to compress 1mb image to 100kb, but i am getting size of that image is 20kb. But i need that 1mb(or 2mb (or) 3mb (or) 4mb (or) 5mb.....) image also get resize to 100kb. and my code is,,
private Bitmap getResizedBitmap(Bitmap bm, int maxSize)
{
int width = bm.getWidth();
int height = bm.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 0) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(bm, width, height, true);
}
public static Bitmap getResizedBitmap(Bitmap bm, float newHeight, float newWidth) {
float width = bm.getWidth();
float height = bm.getHeight();
float scaleWidth = (newWidth) / width;
float scaleHeight = (newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
return Bitmap.createBitmap(bm, 0, 0, (int) width, (int) height, matrix, false);
}
Using matrix
Resizing bitmap by pixel resolution is possible but resizing by its disk size is not as far as I know
I have been searching but i did not find a question about how to pixelize a bitmap in android
Example
Note that i dont mean blur
You could just try and resize that image to a smaller version (and then back up if you need it at the same size as the original for some reason)
{
Bitmap original = ...;
//Calculate proportional size, or make the method accept just a factor of scale.
Bitmap small = getResigetResizedBitmap(original, smallWidth, smallHeight);
Bitmap pixelated = getResigetResizedBitmap(small, normalWidth, normalHeight);
//Recycle small, recycle original if no longer needed.
}
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
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;
}
The code is from here
The simplest way to pixelate the image would be to scale image down using "nearest neighbour" algorithm, and then scale up, using the same algorithm.
Filtering over the image trying to find an average takes much more time, but does not actually give any improvements in result quality, after all you do intentionally want your image distorted.
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;
}
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".
I am fetching number of images and text related to it from server
Now i want to set each image with text(at bottom) in LinearLayout
I got the answer of second part of the question from here
button.setCompoundDrawables(left, top, right, bottom);
But problem with this is I am getting images of different sizes and want to resize them
I am succeded to resizing Button by using Layout Params but with
setCompoundDrawable(left,top,right,bottom); image doesnt get resized
How can i achieve this??
I hope below code was working for you Because Its work fine with me
Bitmap bitmap = ImageResizeUtility.resizeBitmap(bitmap, 100, 110);
Use this class to resize the images
public class ImageResizeUtility
{
public static Bitmap resizeBitmap(final Bitmap bitmap, final int width, final int height)
{
final int oldWidth = bitmap.getWidth();
final int oldHeight = bitmap.getHeight();
final int newWidth = width;
final int newHeight = height;
// calculate the scale
final float scaleWidth = ((float) newWidth) / oldWidth;
final float scaleHeight = ((float) newHeight) / oldHeight;
// create a matrix for the manipulation
final Matrix matrix = new Matrix();
// resize the Bitmap
matrix.postScale(scaleWidth, scaleHeight);
// if you want to rotate the Bitmap
// recreate the new Bitmap
final Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, oldWidth, oldHeight, matrix, true);
return resizedBitmap;
}