591

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?

MiJyn
  • 5,327
  • 4
  • 37
  • 64
michael
  • 106,540
  • 116
  • 246
  • 346

26 Answers26

887
  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.

Community
  • 1
  • 1
Steve Haley
  • 55,374
  • 17
  • 77
  • 85
  • Thanks. But what if I have an ImageView, and I set the image by using imageView.setImageBitmap()? – michael Mar 31 '10 at 03:31
  • 23
    That's the same thing, just done in code rather than XML. `setImageBitmap` is the same as `android:src="..."` and `setBackground...` is `android:background="..."` – Steve Haley Mar 31 '10 at 10:55
  • @SteveHaley i know it is too late but can you please tell me image.setImageDrawable equivalent in xml code –  Apr 27 '13 at 07:40
  • 5
    @SuperUser `image.setImageDrawable(...)` is `android:src="..."` in xml aswell. – PureSpider May 03 '13 at 15:43
  • 14
    "android:adjustViewBounds" is the handy one here to note! if you do not add this, you most likely will have issues with the ImageView border/bounds/container not scaling correctly. – Angry 84 Feb 02 '14 at 03:39
  • android:scaleType="fitCenter" Also seem to work well. It automatically crops such that image fully fits the Image view. – Confuse Sep 06 '14 at 09:32
  • Be aware that adjustViewBounds would not work in case ImageView has exact size specified in layout http://stackoverflow.com/questions/16022841/when-will-measurespec-unspecified-and-measurespec-at-most-be-applied – Kurovsky Jan 23 '15 at 10:48
  • Spot on ! Brilliant answer ...saved a lot of coding...i was going for a custom imageview..thanks a lot ! – sid_09 Aug 01 '15 at 07:15
  • It's awesome! I find your answer for along time. Before that I used adjustViewBounds and setBackground, It wasn't working as well. – nobjta_9x_tq Aug 07 '15 at 07:16
  • 4
    src= vs background= was the difference for me! – Christopher Rathgeb Oct 20 '15 at 02:39
  • 29
    `android:adjustViewBounds` was the last piece to my puzzle, thanks! – themarketka Jan 13 '16 at 21:58
  • Correct answer but I withheld my +1 because IMO your verbosity was unwarranted for this question. Regardless, thank you for your time. – Jacksonkr Mar 11 '16 at 18:47
  • android:adjustViewBounds="true" finally fixed it for me. Thanks. – Evan Sevy Feb 13 '17 at 01:43
313

See android:adjustViewBounds.

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

SMR
  • 6,628
  • 2
  • 35
  • 56
Gratzi
  • 3,139
  • 1
  • 15
  • 2
  • 7
    This is the correct fix for the issue. We were having this on our image view, where the height included all of this extra whitespace. It isn't "transparent pixels", since we had fill_parent for width, and wrap_content for height. If you don't have adjustViewBounds=true, then you get the extra whitespace. After setting that to true, our issue went away. Thanks! – christophercotton Jul 16 '10 at 18:07
  • 3
    thanks, this and setting it to src instead of background worked perfectly! – Cameron Oct 10 '10 at 08:48
  • See also [how-to-scale-bitmap-to-screen-size](http://stackoverflow.com/questions/6410364/how-to-scale-bitmap-to-screen-size) – ThomasRS Jan 11 '12 at 16:40
  • 1
    This is the perfect fix for the issue. Also for the sizes, use the parent container to set the size, and set match_parent in the ImageView. This solves a lot of troubles. – Nimila Hiranya Sep 25 '15 at 08:53
  • +1 for getting to the point. I initially wrote that in a more "colloquial" phrase and sof barred me from submitting it. Rather than ruffle feathers a went PC. – Jacksonkr Mar 11 '16 at 18:49
205

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"
Kevin Parker
  • 16,975
  • 20
  • 76
  • 105
  • 20
    Yes but your image gets cropped. The perfect solution would stretch to width, maintain aspect ratio and not crop. I have no idea why this has to be so anoing to do... – Warpzit Nov 16 '11 at 10:21
  • 1
    Me either :( Sorry if my solution did not help you, but it did help me. – Kevin Parker Nov 16 '11 at 15:33
  • 2
    Kevin, what you said was exactly what i was looking for, if the size of the image is less than that of the screen, it gets zoomed in and centered, perfect. Thanks. – Soham Jan 17 '13 at 11:01
  • 1
    +1, except for "(or other `View`)". AFAICT no other view has `adjustViewBounds` or `scaleType` attributes. – LarsH Sep 08 '15 at 17:21
  • 1
    how about using android:scaleType="centerInside" instead of android:scaleType="centerCrop"? It would also not crop the image but ensure that both width and height are less than or equal the imageview's width and height :) Here's a good visual guide for scaletypes: https://thoughtbot.com/blog/android-imageview-scaletype-a-visual-guide – vida Jan 21 '20 at 23:27
  • @vida I looked through all of these and other questions, and this was the solution that worked for me. It involved no converting and worked perfectly. – petestmart Oct 25 '22 at 16:14
59

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.

biegleux
  • 13,179
  • 11
  • 45
  • 52
Kevin
  • 591
  • 4
  • 2
  • 1
    Why not just use android:scaleType="centerCrop"? – Lukas Batteau Jun 19 '12 at 12:45
  • works like a charm, thanks. scaleType depend on situation, for example i needed exactly this. – David Jan 18 '13 at 17:47
  • This's a little bit barbarian way of resizing the view. What happens if the view bounds change after you set the bitmap to the ImageView? This's why it should be done in onMeasure(), which can be implemented if you make a custom subclass of ImageView. – Aron Lorincz Mar 17 '14 at 13:48
  • 1
    All I needed was the fitCenter and adjustViewBounds, the rest of the code at least for me was unnecessary – kingargyle May 22 '15 at 19:13
  • This works for me and don't need to add any code. Without the adjustViewBounds if the image width was smaller than imageView width, it was not scaling up, so the height was stopping to the native height and on the width some bands did appear. – Cristi Băluță Apr 04 '19 at 04:44
18

This worked for me:

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="39dip"
android:scaleType="centerCrop"
android:adjustViewBounds ="true"
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
Mike6679
  • 5,547
  • 19
  • 63
  • 108
12

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.

Jeet
  • 1,030
  • 2
  • 10
  • 20
11

this solved my problem

android:adjustViewBounds="true"
android:scaleType="fitXY"
Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
9

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.

biegleux
  • 13,179
  • 11
  • 45
  • 52
Samuh
  • 36,316
  • 26
  • 109
  • 116
9

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);
Lukasz 'Severiaan' Grela
  • 6,078
  • 7
  • 43
  • 79
Mukesh Parmar
  • 941
  • 1
  • 15
  • 25
6

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.

Lukasz 'Severiaan' Grela
  • 6,078
  • 7
  • 43
  • 79
halxinate
  • 1,509
  • 15
  • 22
6

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"
    />
Atif Mahmood
  • 8,882
  • 2
  • 41
  • 44
5

If image quality decreases in: use

android:adjustViewBounds="true"

instead of

android:adjustViewBounds="true"
android:scaleType="fitXY"
Pradeep
  • 9,667
  • 13
  • 27
  • 34
Sumit Singh
  • 1,150
  • 13
  • 17
3

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

  • 5
    Nope, this changes the aspect ration. The docs say: "Scale in X and Y independently, so that src matches dst exactly. This may change the aspect ratio of the src." – Rose Perrone May 28 '13 at 19:58
  • By the way, this FIT_XY can not be used for changing the width/height of the image for displaying on the imageview. – Bay Feb 27 '18 at 21:32
  • `ScaleType.FIT_XY` does not preserve the aspect ratio. `ScaleType.FIT_XY` will stretch the image to exactly fit the `ImageView` dimensions. – iCantC Oct 17 '21 at 15:29
3

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);
msevgi
  • 4,828
  • 2
  • 24
  • 30
3

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

imageView.setAdjustViewBounds(true)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)
lukasz
  • 3,121
  • 1
  • 21
  • 20
2

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

android:layout_weight="1"
android:scaleType="fitCenter"
Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90
2

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

Romu Dizzy
  • 113
  • 2
  • 8
1

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" />
Flavio Capaccio
  • 706
  • 4
  • 15
  • I also set `android:adjustViewBounds="true"`. `centerInside` was the way to go to prevent cropping and maintaining the aspect ratio. – Martin Braun May 04 '21 at 00:01
1

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.

ITisha
  • 902
  • 2
  • 12
  • 14
1

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!

Community
  • 1
  • 1
Parth Kapoor
  • 1,494
  • 12
  • 23
1

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);
    }

ppreetikaa
  • 1,149
  • 2
  • 15
  • 22
1

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);
Boken
  • 4,825
  • 10
  • 32
  • 42
0

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>
Alireza Sharifi
  • 1,127
  • 1
  • 9
  • 18
0

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

Niraj
  • 31
  • 4
0

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" />
myworldbox
  • 361
  • 6
  • 11
-5
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 130, 110, false));
kleopatra
  • 51,061
  • 28
  • 99
  • 211