如何在ImageView中缩放图像以保持纵横比


526

在Android中,我所定义的ImageView“S layout_widthfill_parent(可能需要在电话的全宽)。

如果我放的图片ImageView大于layout_width,Android会缩放图片,对吗?但是高度呢?Android缩放图像时,它会保持宽高比吗?

我发现,ImageView当Android缩放的图片大于时,顶部和底部会有一些空白ImageView。真的吗?如果是,如何消除空白?

Answers:


799
  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中的预览通常是错误的。


18
这是同一件事,只是用代码而不是XML完成。setImageBitmap是一样的android:src="...",并setBackground...android:background="..."
史蒂夫海利

4
@SuperUser image.setImageDrawable(...)android:src="..."在XML以及。
PureSpider 2013年

11
“ android:adjustViewBounds”是这里要注意的便捷工具!如果不添加此项,则很有可能会出现ImageView边框/边界/容器无法正确缩放的问题。
2014年

2
src = vs background =对我来说就是区别!
Christopher Rathgeb,2015年

21
android:adjustViewBounds是我困惑的最后一块,谢谢!
themarketka

281

请参阅android:adjustViewBounds

如果您希望ImageView调整其边界以保留其可绘制对象的纵横比,请将其设置为true。


6
这是解决该问题的正确方法。我们在图像视图中使用了此功能,其中高度包括所有这些额外的空白。它不是“透明像素”,因为我们有fill_parent表示宽度,而wrap_content表示高度。如果您没有AdjustViewBounds = true,那么您将获得额外的空格。将其设置为true后,我们的问题就消失了。谢谢!
christophercotton

3
谢谢,这并将其设置为src而不是背景,效果很好!
卡梅伦2010年


1
这是解决此问题的完美方法。另外,对于大小,请使用父容器设置大小,然后在ImageView中设置match_parent。这样解决了很多麻烦。
Nimila Hiranya

+1代表重点。我最初用一个比较“口语化”的词写过,所以禁止我提交。而不是用皱纹代替一台PC。
杰克逊(Jacksonkr)'16

168

对于其他任何遇到此特定问题的人。您有一个ImageView想要fill_parent按比例缩放的宽度和高度:

将这两个属性添加到您的ImageView

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

并将ImageView宽度设置为fill_parent,高度设置为wrap_content

另外,如果您不希望裁剪图像,请尝试以下操作:

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

16
是的,但是您的图像被裁剪了。完美的解决方案将拉伸到宽度,保持长宽比而不是裁切。我不知道为什么必须如此急切地做……
Warpzit

1
我要么:(很抱歉,如果我的解决方案对您没有帮助,但它确实帮助我。
凯文·帕克

2
凯文(Kevin),您所说的正是我想要的,如果图像的尺寸小于屏幕的尺寸,则图像将放大并居中,非常完美。谢谢。
苏厄姆

1
+1,但“(或其他View)” 除外。AFAICT没有其他视图adjustViewBoundsscaleType属性。
LarsH 2015年

如何使用android:scaleType =“ centerInside”而不是android:scaleType =“ centerCrop”?它也不会裁剪图像,但要确保宽度和高度都小于或等于imageview的宽度和高度:)这是一个很好的缩放类型
vida

57

如果要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”?
卢卡斯·巴托

就像魅力一样,谢谢。scaleType取决于情况,例如我确实需要这个。
大卫,

这是调整视图大小的野蛮方式。将位图设置为ImageView后,如果视图范围发生变化,会发生什么情况?这就是为什么应该在onMeasure()中完成的原因,如果您创建ImageView的自定义子类,则可以实现。
Aron Lorincz 2014年

1
我需要的只是fitCenter和AdjustViewBounds,其余的代码至少对我来说是不必要的
kingargyle 2015年

这对我有用,不需要添加任何代码。如果没有AdjustViewBounds,则如果图像宽度小于imageView宽度,则它没有按比例放大,因此该高度停止到原始高度,并且在宽度上确实出现了一些条带。
Cristi Băluță

15

这为我工作:

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


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

8

看一下ImageView.ScaleType来控制和了解在.NET中调整大小的方式ImageView。调整图像大小(同时保持其宽高比)时,图像的高度或宽度可能会小于其ImageView尺寸。


6

在ImageView中使用以下属性以保持纵横比:

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

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

只有这个答案对我有所帮助。谢谢!
德米特里'18

6

这是在ConstraintLayout中为我工作的方式:

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

然后在代码中,将drawable设置为:

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

这可以根据其宽高比很好地拟合图像,并使图像居中。


5

我的图像小于屏幕。为了使其与最大比例成比例地拉伸并在视图中居中,我必须使用以下代码:

<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" />

但是请记住,如果您有相对的布局,并且某些元素设置在ImageView的上方或下方,则它们很可能会被图像重叠。


4

如果图像质量下降,请使用

android:adjustViewBounds="true"

代替

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

3

对于任何想要图像适合图像的人,只要使用适当的缩放比例就可以正确使用图像视图,而无需裁剪

imageView.setScaleType(ScaleType.FIT_XY);

其中imageView是代表您的ImageView的视图


4
不,这会改变宽高比。文档说:“分别缩放X和Y,使src与dst完全匹配。这可能会改变src的长宽比。”
罗斯·佩罗

顺便说一句,此FIT_XY不能用于更改要在imageview上显示的图像的宽度/高度。

3

您可以计算屏幕宽度。您可以缩放位图。

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

计算屏幕宽度和按屏幕宽度缩放的图像高度。

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

之后就可以缩放位图了。

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

3

以编程方式执行此操作时,请确保以正确的顺序调用设置器:

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

2

如果您希望图像占据最大的空间,那么最好的选择是

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

2

不需要任何Java代码。您只需要:

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

关键在宽度和高度的匹配父项中


1

尝试将其android:layout_gravity用于ImageView:

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

上面的例子对我有用。


1
android:layout_weight =“ 1”是关键。
尼玛

1

我有一种算法可以将位图缩放为bestFit容器尺寸,并保持其纵横比。请在这里找到我的解决方案

希望这可以帮助某人!


0

我用这个:

<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" />

0

cardview用于舍入imageview并固定android:layout_height为标题的情况下,这对我来说可以用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>

0

您可以缩放图像,这也会减小图像的尺寸。您可以下载并使用它的库。 https://github.com/niraj124124/Images-Files-scale-and-compress.git

使用方法1)导入压缩机v1.0。罐到您的项目。2)添加以下示例代码进行测试。ResizeLimiter resize = ImageResizer.build(); resize.scale(“ inputImagePath”,“ outputImagePath”,imageWidth,imageHeight); 根据您的要求还有更多方法


0

传递您的ImageView并根据屏幕的高度和宽度进行制作

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


0

快速回答:

<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" />

-5
imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 130, 110, false));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.