如何在ImageView中按比例缩放图像

592
在Android中,我将一个ImageViewlayout_width定义为fill_parent(占据手机的全部宽度)。
如果我放入ImageView的图片尺寸比layout_width大,那么Android会对其进行缩放,对吗?但是高度呢?当Android缩放图片时,它是否保持长宽比?
我发现,当Android缩放比ImageView更大的图片时,在ImageView的顶部和底部会出现一些白色空间。这是真的吗?如果是,我该如何消除这些白色空间?
26个回答

890
  1. 默认情况下,Android将缩放您的图像以适应ImageView,并保持其纵横比。但是,请确保使用android:src="..."将图像设置到ImageView中,而不是android:background="..."src=会使其按比例缩放图像,但background=会使其缩放并扭曲图片使其恰好适应ImageView的大小。(您可以同时使用背景和源,这对于诸如在主要图像周围显示框架等内容非常有用,只需要一个ImageView。)

  2. 还应该查看android:adjustViewBounds来使ImageView调整自身大小以适应重新缩放后的图像。例如,如果在正常情况下为方形ImageView中有一个矩形图像,则adjustViewBounds=true将使其调整ImageView也成为矩形。然后这会影响ImageView周围其他视图的布局。

    然后,正如Samuh所写的那样,您可以使用android:scaleType参数更改其默认缩放图像的方式。顺便说一句,发现这是如何工作的最简单方法就是自己进行一些实验!只需记住查看模拟器本身(或实际手机)中的布局,因为Eclipse中的预览通常是错误的。


23
这两者本质相同,只是用代码实现而非XML。setImageBitmapandroid:src="..."等效,而setBackground...则相当于android:background="..." - Steve Haley
5
image.setImageDrawable(...)在Android中设置图片,与xml中的android:src="..."作用相同。 - PureSpider
14
这里需要注意的是"android:adjustViewBounds"属性!如果你不加上它,你很可能会遇到ImageView边框/边界/容器没有正确缩放的问题。 - Angry 84
4
对我来说,src=和background=的区别在于:前者用于指定要显示的图像文件的URL路径,而后者则用于设置一个元素的背景图像。 - Christopher Rathgeb
29
android:adjustViewBounds 是我问题的最后一块拼图,谢谢! - themarketka
显示剩余8条评论

313

请查看android:adjustViewBounds

将其设置为true,如果您希望ImageView调整其边界以保持其可绘制对象的宽高比。


7
这是解决问题的正确方法。我们在图像视图上遇到了这个问题,其中高度包括所有额外的空白。这不是“透明像素”,因为我们宽度设置为fill_parent,高度设置为wrap_content。如果您没有将adjustViewBounds设置为true,则会出现额外的空白。将其设置为true后,我们的问题消失了。谢谢! - christophercotton
3
谢谢,将其设置为“src”而不是“background”完美解决了问题! - Cameron
请参见 如何将位图缩放到屏幕大小 - ThomasRS
1
这是解决问题的完美方法。对于尺寸,使用父容器来设置大小,并在ImageView中设置match_parent。这解决了许多麻烦。 - Nimila Hiranya
+1 是为了直接表达观点。我最初用了更加“口语化”的措辞,但是软件禁止我提交。为了避免引起不必要的麻烦,我选择了更加正式的措辞。 - Jacksonkr

206

对于其他遇到此问题的人,您有一个希望宽度为fill_parent且高度按比例缩放的ImageView

将以下两个属性添加到您的 ImageView 中:

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

ImageView 的宽度设置为 fill_parent,高度设置为 wrap_content

另外,如果您不希望图像被裁剪,请尝试以下方法:

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

20
是的,但是您的图像会被裁剪。完美的解决方案应该可以自适应宽度,保持长宽比并且不裁剪。我不知道为什么这样做会那么让人恼火... - Warpzit
1
我也一样:( 很抱歉我的解决方案没有帮到你,但它确实帮了我。 - Kevin Parker
2
Kevin,你说的正是我在寻找的,如果图像的尺寸小于屏幕的尺寸,它会被放大并居中,非常完美。谢谢。 - Soham
1
除了“(或其他View)”之外,+1。据我所知,没有其他视图具有adjustViewBoundsscaleType属性。 - LarsH
1
使用android:scaleType="centerInside"代替android:scaleType="centerCrop"怎么样?这样不会裁剪图像,而是确保宽度和高度都小于或等于imageview的宽度和高度 :) 这里有一个很好的缩放类型视觉指南:https://thoughtbot.com/blog/android-imageview-scaletype-a-visual-guide - vida
@vida 我查看了所有这些和其他问题,这是对我有效的解决方案。它不需要转换就可以完美地工作。 - petestmart

59

如果你想要一个ImageView,可以在保持正确的宽高比的同时进行缩放,可以在XML中添加以下内容:

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

将以下代码添加到你的程序中:

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

我花了一些时间才让它工作,但这似乎适用于图像小于屏幕宽度和大于屏幕宽度的情况,并且不会将图像装入一个框中。


1
为什么不直接使用android:scaleType="centerCrop"呢? - Lukas Batteau
非常好用,谢谢。scaleType取决于情况,例如我需要的就是这个。 - David
这是一种有点野蛮的调整视图大小的方法。如果在将位图设置到ImageView之后,视图边界发生更改会发生什么?这就是为什么应该在onMeasure()中完成,如果您创建了ImageView的自定义子类,则可以实现此功能。 - Aron Lorincz
1
我所需要的只是fitCenter和adjustViewBounds,至少对我来说,其余的代码都是不必要的。 - kingargyle
这对我来说很有效,不需要添加任何代码。如果没有adjustViewBounds,如果图像宽度小于imageView宽度,则不会进行缩放,因此高度会停止在本地高度,并且在宽度上会出现一些带状物。 - Cristi Băluță

18

这个方法对我有效:

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

12

这是在 ConstraintLayout 中对我起作用的方式:

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

然后在代码中,我将可绘制对象设置为:

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

根据其宽高比,此项完美地适配了图像并使其保持居中。


11

这解决了我的问题。

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

它对我来说无法保持图像的纵横比。 - Dmitry

9

以下代码可按比例缩放图像:

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

9
看一下 ImageView.ScaleType,以控制和理解在 ImageView 中调整大小发生的方式。当图像被调整大小(同时保持其纵横比)时,很有可能图像的高度或宽度变得小于 ImageView 的尺寸。

7

在ImageView中使用以下属性来保持宽高比:

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

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

只有这个答案对我有帮助。谢谢! - Dmitry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接