How to Resize a Bitmap in Android?

AndroidBitmapBase64

Android Problem Overview


I have a bitmap taken of a Base64 String from my remote database, (encodedImage is the string representing the image with Base64):

profileImage = (ImageView)findViewById(R.id.profileImage);

byte[] imageAsBytes=null;
try {
    imageAsBytes = Base64.decode(encodedImage.getBytes());
} catch (IOException e) {e.printStackTrace();}

profileImage.setImageBitmap(
    BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
);

profileImage is my ImageView

Ok, but I have to resize this image before showing it on my ImageView of my layout. I have to resize it to 120x120.

Can someone tell me the code to resize it?

The examples I found could not be applied to a base64 string obtained bitmap.

Android Solutions


Solution 1 - Android

Change:

profileImage.setImageBitmap(
    BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)

To:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));

Solution 2 - Android

import android.graphics.Matrix
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);
    bm.recycle();
	return resizedBitmap;
}

EDIT: as suggested by by @aveschini, I have added bm.recycle(); in order to avoid the memory leaks. Please note that in case if you are using the previous object for some other purposes, then handle accordingly.

Solution 3 - Android

If you already have a bitmap, you could use the following code to resize:

Bitmap originalBitmap = <original initialization>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
    originalBitmap, newWidth, newHeight, false);

Solution 4 - Android

Scale based on aspect ratio:

float aspectRatio = yourSelectedImage.getWidth() / 
    (float) yourSelectedImage.getHeight();
int width = 480;
int height = Math.round(width / aspectRatio);

yourSelectedImage = Bitmap.createScaledBitmap(
    yourSelectedImage, width, height, false);

To use height as base intead of width change to:

int height = 480;
int width = Math.round(height * aspectRatio);

Solution 5 - Android

Scale a bitmap with a target maximum size and width, while maintaining aspect ratio:

int maxHeight = 2000;
int maxWidth = 2000;    
float scale = Math.min(((float)maxHeight / bitmap.getWidth()), ((float)maxWidth / bitmap.getHeight()));
    
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);

bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

Solution 6 - Android

try this this code :

BitmapDrawable drawable = (BitmapDrawable) imgview.getDrawable();
Bitmap bmp = drawable.getBitmap();
Bitmap b = Bitmap.createScaledBitmap(bmp, 120, 120, false);

I hope it's useful.

Solution 7 - Android

Someone asked how to keep aspect ratio in this situation:

Calculate the factor you are using for scaling and use it for both dimensions. Let´s say you want an image to be 20% of the screen in height

int scaleToUse = 20; // this will be our percentage
Bitmap bmp = BitmapFactory.decodeResource(
    context.getResources(), R.drawable.mypng);
int sizeY = screenResolution.y * scaleToUse / 100;
int sizeX = bmp.getWidth() * sizeY / bmp.getHeight();
Bitmap scaled = Bitmap.createScaledBitmap(bmp, sizeX, sizeY, false);

for getting the screen resolution you have this solution: https://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels

Solution 8 - Android

Although the accepted answer is correct, it doesn't resize Bitmap by keeping the same Aspect Ratio. If you are looking for a method to resize Bitmap by keeping the same aspect ratio you can use the following utility function. The usage details and explanation of the function are present at this link.

public static Bitmap resizeBitmap(Bitmap source, int maxLength) {
       try {
           if (source.getHeight() >= source.getWidth()) {
               int targetHeight = maxLength;
               if (source.getHeight() <= targetHeight) { // if image already smaller than the required height
                   return source;
               }

               double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
               int targetWidth = (int) (targetHeight * aspectRatio);

               Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
               if (result != source) {
               }
               return result;
           } else {
               int targetWidth = maxLength;

               if (source.getWidth() <= targetWidth) { // if image already smaller than the required height
                   return source;
               }

               double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
               int targetHeight = (int) (targetWidth * aspectRatio);

               Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
               if (result != source) {
               }
               return result;

           }
       }
       catch (Exception e)
       {
           return source;
       }
   }

Solution 9 - Android

profileImage.setImageBitmap(
    Bitmap.createScaledBitmap(
        BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length), 
        80, 80, false
    )
);

Solution 10 - Android

Try this: This function resizes a bitmap proportionally. When the last parameter is set to "X" the newDimensionXorY is treated as s new width and when set to "Y" a new height.

public Bitmap getProportionalBitmap(Bitmap bitmap, 
                                    int newDimensionXorY, 
                                    String XorY) {
	if (bitmap == null) {
		return null;
	}

	float xyRatio = 0;
	int newWidth = 0;
	int newHeight = 0;

	if (XorY.toLowerCase().equals("x")) {
		xyRatio = (float) newDimensionXorY / bitmap.getWidth();
		newHeight = (int) (bitmap.getHeight() * xyRatio);
		bitmap = Bitmap.createScaledBitmap(
            bitmap, newDimensionXorY, newHeight, true);
	} else if (XorY.toLowerCase().equals("y")) {
		xyRatio = (float) newDimensionXorY / bitmap.getHeight();
		newWidth = (int) (bitmap.getWidth() * xyRatio);
		bitmap = Bitmap.createScaledBitmap(
            bitmap, newWidth, newDimensionXorY, true);
	}
	return bitmap;
}

Solution 11 - Android

  public Bitmap scaleBitmap(Bitmap mBitmap) {
        int ScaleSize = 250;//max Height or width to Scale
        int width = mBitmap.getWidth();
        int height = mBitmap.getHeight();
        float excessSizeRatio = width > height ? width / ScaleSize : height / ScaleSize;
         Bitmap bitmap = Bitmap.createBitmap(
                mBitmap, 0, 0,(int) (width/excessSizeRatio),(int) (height/excessSizeRatio));
        //mBitmap.recycle(); if you are not using mBitmap Obj
        return bitmap;
    }

Solution 12 - Android

Bitmap Resize based on Any Display size

public Bitmap bitmapResize(Bitmap imageBitmap) {

	Bitmap bitmap = imageBitmap;
	float heightbmp = bitmap.getHeight();
	float widthbmp = bitmap.getWidth();

	// Get Screen width
	DisplayMetrics displaymetrics = new DisplayMetrics();
	this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
	float height = displaymetrics.heightPixels / 3;
	float width = displaymetrics.widthPixels / 3;

	int convertHeight = (int) hight, convertWidth = (int) width;

	// higher
	if (heightbmp > height) {
		convertHeight = (int) height - 20;
		bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
				convertHighet, true);
	}

	// wider
	if (widthbmp > width) {
		convertWidth = (int) width - 20;
		bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
				convertHeight, true);
	}

	return bitmap;
}

Solution 13 - Android

public static Bitmap resizeBitmapByScale(
            Bitmap bitmap, float scale, boolean recycle) {
        int width = Math.round(bitmap.getWidth() * scale);
        int height = Math.round(bitmap.getHeight() * scale);
        if (width == bitmap.getWidth()
                && height == bitmap.getHeight()) return bitmap;
        Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
        Canvas canvas = new Canvas(target);
        canvas.scale(scale, scale);
        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
        canvas.drawBitmap(bitmap, 0, 0, paint);
        if (recycle) bitmap.recycle();
        return target;
    }
    private static Bitmap.Config getConfig(Bitmap bitmap) {
        Bitmap.Config config = bitmap.getConfig();
        if (config == null) {
            config = Bitmap.Config.ARGB_8888;
        }
        return config;
    }

Solution 14 - Android

As of API 19, Bitmap setWidth(int width) and setHeight(int height) exist. http://developer.android.com/reference/android/graphics/Bitmap.html

Solution 15 - Android

/**
 * Kotlin method for Bitmap scaling
 * @param bitmap the bitmap to be scaled
 * @param pixel  the target pixel size
 * @param width  the width
 * @param height the height
 * @param max    the max(height, width)
 * @return the scaled bitmap
 */
fun scaleBitmap(bitmap:Bitmap, pixel:Float, width:Int, height:Int, max:Int):Bitmap {
    val scale = px / max
    val h = Math.round(scale * height)
    val w = Math.round(scale * width)
    return Bitmap.createScaledBitmap(bitmap, w, h, true)
  }

Solution 16 - Android

Keeping the aspect ratio,

  public Bitmap resizeBitmap(Bitmap source, int width,int height) {
    if(source.getHeight() == height && source.getWidth() == width) return source;
    int maxLength=Math.min(width,height);
    try {
        source=source.copy(source.getConfig(),true);
        if (source.getHeight() <= source.getWidth()) {
            if (source.getHeight() <= maxLength) { // if image already smaller than the required height
                return source;
            }

            double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
            int targetWidth = (int) (maxLength * aspectRatio);

            return Bitmap.createScaledBitmap(source, targetWidth, maxLength, false);
        } else {

            if (source.getWidth() <= maxLength) { // if image already smaller than the required height
                return source;
            }

            double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
            int targetHeight = (int) (maxLength * aspectRatio);

            return Bitmap.createScaledBitmap(source, maxLength, targetHeight, false);

        }
    }
    catch (Exception e)
    {
        return source;
    }
}

Solution 17 - Android

While the previous answers do scale the image and take care of the aspect ratio, the resampling itself should be done so that there is no aliasing. Taking care of scale is a matter of fixing arguments correctly. There are many comments about the quality of the output images from standard scaling call. to maintain quality of the image one should use the standard call:

Bitmap resizedBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);

with the last argument set to true because it will do the bilinear filtering for resampling to prevent aliasing. Read more about aliasing here: https://en.wikipedia.org/wiki/Aliasing

From android documentation:

https://developer.android.com/reference/android/graphics/Bitmap#createScaledBitmap(android.graphics.Bitmap,%20int,%20int,%20boolean)


public static Bitmap createScaledBitmap (Bitmap src,
int dstWidth,
int dstHeight,
boolean filter)

filter : boolean, Whether or not bilinear filtering should be used when scaling the bitmap. If this is true then bilinear filtering will be used when scaling which has better image quality at the cost of worse performance. If this is false then nearest-neighbor scaling is used instead which will have worse image quality but is faster. Recommended default is to set filter to 'true' as the cost of bilinear filtering is typically minimal and the improved image quality is significant.

Solution 18 - Android

* For resize bitmap with width and height ratio.    

public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
            int width = image.getWidth();
            int height = image.getHeight();
    
            float bitmapRatio = (float) width / (float) height;
            if (bitmapRatio > 1) {
                width = maxSize;
                height = (int) (width / bitmapRatio);
            } else {
                height = maxSize;
                width = (int) (height * bitmapRatio);
            }
            return Bitmap.createScaledBitmap(image, width, height, true);
        }

Solution 19 - Android

apply Matrix.ScaleToFit.CENTER) for getting a new bitmap keeps aspect ratio.

public static Bitmap getScaledwonBitmap(Bitmap srcBmp, int deisredWidth, int desiredHeight) {
        
            Matrix matrix = new Matrix();
            matrix.setRectToRect(new RectF(0, 0, srcBmp.getWidth(), srcBmp.getHeight()),
                    new RectF(0, 0, deisredWidth, desiredHeight),
                    Matrix.ScaleToFit.CENTER);
           return Bitmap.createBitmap(srcBmp, 0, 0, srcBmp.getWidth(), srcBmp.getHeight(), matrix, true);
        
    }

Solution 20 - Android

      Try this kotlin code for resize....Where Max size any size you 
      want

      fun getResizedBitmap(image: Bitmap?, maxSize: Int): Bitmap {
    var width = image!!.width
    var height = image.height
    val bitmapRatio = width.toFloat() / height.toFloat()
     if (bitmapRatio > 0) {
        width = maxSize
        height = (width / bitmapRatio).toInt()
     } else {
        height = maxSize
         width = (height * bitmapRatio).toInt()
     }
         return Bitmap.createScaledBitmap(image, width, height, true)
     }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNullPointerExceptionView Question on Stackoverflow
Solution 1 - Androiduser432209View Answer on Stackoverflow
Solution 2 - Androidjeet.chanchawatView Answer on Stackoverflow
Solution 3 - AndroidZenBalanceView Answer on Stackoverflow
Solution 4 - AndroidRenato ProbstView Answer on Stackoverflow
Solution 5 - AndroidKevinView Answer on Stackoverflow
Solution 6 - AndroidRavi MakvanaView Answer on Stackoverflow
Solution 7 - AndroidTaochokView Answer on Stackoverflow
Solution 8 - AndroidAsad Ali ChoudhryView Answer on Stackoverflow
Solution 9 - AndroidRajkamalView Answer on Stackoverflow
Solution 10 - Androiduser2288580View Answer on Stackoverflow
Solution 11 - AndroidSandeep PView Answer on Stackoverflow
Solution 12 - Androiduser4696837View Answer on Stackoverflow
Solution 13 - AndroidkakopappaView Answer on Stackoverflow
Solution 14 - AndroidafathmanView Answer on Stackoverflow
Solution 15 - AndroidFaakhirView Answer on Stackoverflow
Solution 16 - AndroidTarasantanView Answer on Stackoverflow
Solution 17 - AndroidAshutosh GuptaView Answer on Stackoverflow
Solution 18 - AndroidPraful ParmarView Answer on Stackoverflow
Solution 19 - AndroidlannyfView Answer on Stackoverflow
Solution 20 - Androidfazal ur RehmanView Answer on Stackoverflow