How to scale an Image in ImageView to keep the aspect ratio

AndroidAndroid ImageviewImage Scaling

Android Problem Overview


In Android, I defined an ImageView's layout_width to be fill_parent (which takes up the full width of the phone).

If the image I put to ImageView is bigger than the layout_width, Android will scale it, right? But what about the height? When Android scales the image, will it keep the aspect ratio?

What I find out is that there is some white space at the top and bottom of the ImageView when Android scales an image which is bigger than the ImageView. Is that true? If yes, how can I eliminate that white space?

Android Solutions


Solution 1 - Android

  1. Yes, by default Android will scale your image down to fit the ImageView, maintaining the aspect ratio. However, make sure you're setting the image to the ImageView using android:src="..." rather than android:background="...". src= makes it scale the image maintaining aspect ratio, but background= makes it scale and distort the image to make it fit exactly to the size of the ImageView. (You can use a background and a source at the same time though, which can be useful for things like displaying a frame around the main image, using just one ImageView.)

  2. You should also see android:adjustViewBounds to make the ImageView resize itself to fit the rescaled image. For example, if you have a rectangular image in what would normally be a square ImageView, adjustViewBounds=true will make it resize the ImageView to be rectangular as well. This then affects how other Views are laid out around the ImageView.

    Then as Samuh wrote, you can change the way it default scales images using the android:scaleType parameter. By the way, the easiest way to discover how this works would simply have been to experiment a bit yourself! Just remember to look at the layouts in the emulator itself (or an actual phone) as the preview in Eclipse is usually wrong.

Solution 2 - Android

See android:adjustViewBounds.

> Set this to true if you want the ImageView to adjust its bounds to preserve the aspect ratio of its drawable.

Solution 3 - Android

To anyone else having this particular issue. You have an ImageView that you want to have a width of fill_parent and a height scaled proportionately:

Add these two attributes to your ImageView:

android:adjustViewBounds="true"
android:scaleType="centerCrop"

And set the ImageView width to fill_parent and height to wrap_content.

Also, if you don't want your image to be cropped, try this:

 android:adjustViewBounds="true"
 android:layout_centerInParent="true"

Solution 4 - Android

If you want an ImageView that both scales up and down while keeping the proper aspect ratio, add this to your XML:

android:adjustViewBounds="true"
android:scaleType="fitCenter"

Add this to your code:

// We need to adjust the height if the width of the bitmap is
// smaller than the view width, otherwise the image will be boxed.
final double viewWidthToBitmapWidthRatio = (double)image.getWidth() / (double)bitmap.getWidth();
image.getLayoutParams().height = (int) (bitmap.getHeight() * viewWidthToBitmapWidthRatio);

It took me a while to get this working, but this appears to work in the cases both where the image is smaller than the screen width and larger than the screen width, and it does not box the image.

Solution 5 - Android

This worked for me:

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="39dip"
android:scaleType="centerCrop"
android:adjustViewBounds ="true"

Solution 6 - Android

This is how it worked for me inside a ConstraintLayout:

<ImageView
    android:id="@+id/myImg"
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"/>

Then in code, I set the drawable as:

ImageView imgView = findViewById(R.id.myImg);
imgView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.image_to_show, null));

This fits the image nicely according to its aspect ratio and keeps it in centre.

Solution 7 - Android

this solved my problem

android:adjustViewBounds="true"
android:scaleType="fitXY"

Solution 8 - Android

Take a look at ImageView.ScaleType to control and understand the way resizing happens in an ImageView. When the image is resized (while maintaining its aspect ratio), chances are that either the image's height or width becomes smaller than ImageView's dimensions.

Solution 9 - Android

Below code Working for scale image as aspect ratio:

Bitmap bitmapImage = BitmapFactory.decodeFile("Your path");
int nh = (int) ( bitmapImage.getHeight() * (512.0 / bitmapImage.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, 512, nh, true);
your_imageview.setImageBitmap(scaled);

Solution 10 - Android

I have an image smaller than the screen. To have it stretched proportionally to the max and centered in the view I had to use the following code:

<ImageView
    android:id="@+id/my_image"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_centerInParent="true"
    android:adjustViewBounds="true"
    android:layout_weight="1"
    android:scaleType="fitCenter" />

Have in mind though, that if you have a relative layout and have some elements set to be above or below the ImageView, they will be most likely overlapped by the image.

Solution 11 - Android

Use these properties in ImageView to keep aspect ratio:

android:adjustViewBounds="true"
android:scaleType="fitXY"

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    />

Solution 12 - Android

If image quality decreases in: use

android:adjustViewBounds="true"

instead of

android:adjustViewBounds="true"
android:scaleType="fitXY"

Solution 13 - Android

For anyone of you who wants the image to fit exact the imageview with proper scaling and no cropping use

imageView.setScaleType(ScaleType.FIT_XY);

where imageView is the view representing your ImageView

Solution 14 - Android

You can calculate screen width. And you can scale bitmap.

 public static float getScreenWidth(Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        display.getMetrics(outMetrics);
        float pxWidth = outMetrics.widthPixels;
        return pxWidth;
    }

calculate screen width and scaled image height by screen width.

float screenWidth=getScreenWidth(act)
  float newHeight = screenWidth;
  if (bitmap.getWidth() != 0 && bitmap.getHeight() != 0) {
     newHeight = (screenWidth * bitmap.getHeight()) / bitmap.getWidth();
  }

After you can scale bitmap.

Bitmap scaledBitmap=Bitmap.createScaledBitmap(bitmap, (int) screenWidth, (int) newHeight, true);

Solution 15 - Android

When doing this programmatically, be sure to call the setters in the correct order:

imageView.setAdjustViewBounds(true)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)

Solution 16 - Android

If you want your image occupy the maximum possible space then the best option would be

android:layout_weight="1"
android:scaleType="fitCenter"

Solution 17 - Android

Yo don't need any java code. You just have to :

<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />

The key is in the match parent for width and height

Solution 18 - Android

I use this:

<ImageView
android:id="@+id/logo"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="centerInside"
android:src="@drawable/logo" />

Solution 19 - Android

Try using android:layout_gravity for ImageView:

android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="1"

The example above worked for me.

Solution 20 - Android

I have an algorithm to scale a bitmap to bestFit the container dimensions, maintaining its aspect ratio. Please find my solution here

Hope this helps someone down the lane!

Solution 21 - Android

Pass your ImageView and based on screen height and width you can make it

    public void setScaleImage(EventAssetValueListenerView view){
        // Get the ImageView and its bitmap
        Drawable drawing = view.getDrawable();
        Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
        // Get current dimensions
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        float xScale = ((float) 4) / width;
        float yScale = ((float) 4) / height;
        float scale = (xScale <= yScale) ? xScale : yScale;

        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);

        Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        BitmapDrawable result = new BitmapDrawable(scaledBitmap);
        width = scaledBitmap.getWidth();
        height = scaledBitmap.getHeight();

        view.setImageDrawable(result);

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
        params.width = width;
        params.height = height;
        view.setLayoutParams(params);
    }

Solution 22 - Android

Programatically apply aspect ratio to Imageview:

aspectRatio = imageWidth/imageHeight   
ratioOfWidth = imageWidth/maxWidth  
ratioOfHeight = imageHeight/maxHeight  


if(ratioOfWidth > ratioOfHeight){​​​​​​​
    imageWidth = maxWidth 
    imageHeight = imageWidth/aspectRatio
}​​​​​​​ else if(ratioOfHeight > ratioOfWidth){​​​​​​​
    imageHeight = maxHeight
    imageWidth = imageHeight * aspectRatio
}​​​​​​​

After that you can use scaled bitmap to image view

Bitmap scaledBitmap= Bitmap.createScaledBitmap(bitmap, (int) imageWidth , (int) imageHeight , true);

Solution 23 - Android

in case of using cardviewfor rounding imageview and fixed android:layout_height for header this worked for me to load image with Glide

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="220dp"
             xmlns:card_view="http://schemas.android.com/apk/res-auto"
             >

    <android.support.v7.widget.CardView
            android:id="@+id/card_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center|top"
            card_view:cardBackgroundColor="@color/colorPrimary"
            card_view:cardCornerRadius="10dp"
            card_view:cardElevation="10dp"
            card_view:cardPreventCornerOverlap="false"
            card_view:cardUseCompatPadding="true">

        <ImageView
                android:adjustViewBounds="true"
                android:maxHeight="220dp"
                android:id="@+id/iv_full"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="fitCenter"/>

    </android.support.v7.widget.CardView>
</FrameLayout>

Solution 24 - Android

You can scale image that will also reduce the size of your image. There is a library for it you can download and use it. https://github.com/niraj124124/Images-Files-scale-and-compress.git

How to use 1)Import the compressor-v1.0. jar to your project. 2)Add the below sample code to test. ResizeLimiter resize = ImageResizer.build(); resize.scale("inputImagePath", "outputImagePath",imageWidth, imageHeight); Many more methods are there according to your requirement

Solution 25 - Android

Quick answer:

<ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="center"
        android:src="@drawable/yourImage"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

Solution 26 - Android

imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 130, 110, false));

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
QuestionmichaelView Question on Stackoverflow
Solution 1 - AndroidSteve HaleyView Answer on Stackoverflow
Solution 2 - AndroidGratziView Answer on Stackoverflow
Solution 3 - AndroidKevin ParkerView Answer on Stackoverflow
Solution 4 - AndroidKevinView Answer on Stackoverflow
Solution 5 - AndroidMike6679View Answer on Stackoverflow
Solution 6 - AndroidJeetView Answer on Stackoverflow
Solution 7 - Androidshafiq-ur-rehmanView Answer on Stackoverflow
Solution 8 - AndroidSamuhView Answer on Stackoverflow
Solution 9 - AndroidMukesh ParmarView Answer on Stackoverflow
Solution 10 - AndroidhalxinateView Answer on Stackoverflow
Solution 11 - AndroidAtif MahmoodView Answer on Stackoverflow
Solution 12 - AndroiddeveloperSumitView Answer on Stackoverflow
Solution 13 - AndroidoneConsciousnessView Answer on Stackoverflow
Solution 14 - AndroidmsevgiView Answer on Stackoverflow
Solution 15 - AndroidlukaszView Answer on Stackoverflow
Solution 16 - AndroidMohsen AfshinView Answer on Stackoverflow
Solution 17 - AndroidRomu DizzyView Answer on Stackoverflow
Solution 18 - AndroidFlavio CapaccioView Answer on Stackoverflow
Solution 19 - AndroidITishaView Answer on Stackoverflow
Solution 20 - AndroidParth KapoorView Answer on Stackoverflow
Solution 21 - Androiduser2100931View Answer on Stackoverflow
Solution 22 - AndroidKaviyarasan MView Answer on Stackoverflow
Solution 23 - Androidlvl4fi4View Answer on Stackoverflow
Solution 24 - AndroidNirajView Answer on Stackoverflow
Solution 25 - AndroidmyworldboxView Answer on Stackoverflow
Solution 26 - Androiduser2099162View Answer on Stackoverflow