将图像调整到ImageView中,保持纵横比,然后将ImageView调整为图像尺寸?

时间:2011-11-22 19:29:56

标签: android imageview scale

如何将随机大小的图像拟合到ImageView
当:

  • 最初ImageView尺寸为250dp * 250dp
  • 图像的较大尺寸应按比例放大/缩小至250dp
  • 图像应保持其宽高比
  • 缩放后,ImageView尺寸应与缩放图像的尺寸相匹配

E.g。对于100 * 150的图像,图像和ImageView应为166 * 250 例如。对于150 * 100的图像,图像和ImageView应为250 * 166。

如果我将界限设置为

<ImageView
    android:id="@+id/picture"
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:adjustViewBounds="true" />

图片恰好适合ImageView,但ImageView始终为250dp * 250dp。

17 个答案:

答案 0 :(得分:203)

对于这个具体问题可能无法回答,但如果有人和我一样,在保留宽高比然后摆脱宽限期的同时搜索如何在ImageView中使用有界大小(例如maxWidth)来匹配图像的答案ImageView占用的空间过多,那么最简单的解决方案就是在XML中使用以下属性:

    android:scaleType="centerInside"
    android:adjustViewBounds="true"

答案 1 :(得分:131)

(在澄清原始问题后,答案被大量修改)

澄清后:
无法仅在xml中完成。无法缩放图像和ImageView,因此图像的一维尺寸始终为250dp,而ImageView的尺寸与图像尺寸相同。

此代码缩放Drawable的{​​{1}}以保持250dp x 250dp的正方形,其中一维精确到250dp并保持纵横比。然后调整ImageView的大小以匹配缩放图像的尺寸。代码用于活动。我通过按钮点击处理程序测试了它。

享受。 :)

ImageView

private void scaleImage(ImageView view) throws NoSuchElementException { // Get bitmap from the the ImageView. Bitmap bitmap = null; try { Drawable drawing = view.getDrawable(); bitmap = ((BitmapDrawable) drawing).getBitmap(); } catch (NullPointerException e) { throw new NoSuchElementException("No drawable on given view"); } catch (ClassCastException e) { // Check bitmap is Ion drawable bitmap = Ion.with(view).getBitmap(); } // Get current dimensions AND the desired bounding box int width = 0; try { width = bitmap.getWidth(); } catch (NullPointerException e) { throw new NoSuchElementException("Can't find bitmap on given view/drawable"); } int height = bitmap.getHeight(); int bounding = dpToPx(250); Log.i("Test", "original width = " + Integer.toString(width)); Log.i("Test", "original height = " + Integer.toString(height)); Log.i("Test", "bounding = " + Integer.toString(bounding)); // Determine how much to scale: the dimension requiring less scaling is // closer to the its side. This way the image always stays inside your // bounding box AND either x/y axis touches it. float xScale = ((float) bounding) / width; float yScale = ((float) bounding) / height; float scale = (xScale <= yScale) ? xScale : yScale; Log.i("Test", "xScale = " + Float.toString(xScale)); Log.i("Test", "yScale = " + Float.toString(yScale)); Log.i("Test", "scale = " + Float.toString(scale)); // Create a matrix for the scaling and add the scaling data Matrix matrix = new Matrix(); matrix.postScale(scale, scale); // Create a new bitmap and convert it to a format understood by the ImageView Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); width = scaledBitmap.getWidth(); // re-use height = scaledBitmap.getHeight(); // re-use BitmapDrawable result = new BitmapDrawable(scaledBitmap); Log.i("Test", "scaled width = " + Integer.toString(width)); Log.i("Test", "scaled height = " + Integer.toString(height)); // Apply the scaled bitmap view.setImageDrawable(result); // Now change ImageView's dimensions to match the scaled image LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); params.width = width; params.height = height; view.setLayoutParams(params); Log.i("Test", "done"); } private int dpToPx(int dp) { float density = getApplicationContext().getResources().getDisplayMetrics().density; return Math.round((float)dp * density); }

ImageView


感谢有关缩放代码的讨论:
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html


2012年11月7日更新:
添加了空白指针检查,如注释

中所示

答案 2 :(得分:38)

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

答案 3 :(得分:21)

下面的代码使得位图与imageview的大小完全相同。获取位图图像的高度和宽度,然后借助imageview的参数计算新的高度和宽度。这为您提供了最佳纵横比所需的图像。

int currentBitmapWidth = bitMap.getWidth();
int currentBitmapHeight = bitMap.getHeight();

int ivWidth = imageView.getWidth();
int ivHeight = imageView.getHeight();
int newWidth = ivWidth;

newHeight = (int) Math.floor((double) currentBitmapHeight *( (double) new_width / (double) currentBitmapWidth));

Bitmap newbitMap = Bitmap.createScaledBitmap(bitMap, newWidth, newHeight, true);

imageView.setImageBitmap(newbitMap)

享受。

答案 4 :(得分:12)

尝试将android:scaleType="fitXY"添加到您的ImageView

答案 5 :(得分:7)

在搜索了一天之后,我认为这是最简单的解决方案:

imageView.getLayoutParams().width = 250;
imageView.getLayoutParams().height = 250;
imageView.setAdjustViewBounds(true);

答案 6 :(得分:5)

这一切都可以使用XML完成......其他方法看起来相当复杂。 无论如何,你只需将高度设置为你想要的dp,然后设置宽度以包装内容,反之亦然。使用scaleType fitCenter调整图像的大小。

std::vector<TokenRule *> tokenRules(3) = {
                                   ^^^^

答案 7 :(得分:5)

在大多数情况下有效的最佳解决方案是

以下是一个例子:

<ImageView android:id="@+id/avatar"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:scaleType="fitXY"/>

答案 8 :(得分:4)

使用此代码:

<ImageView android:id="@+id/avatar"
           android:layout_width="fill_parent"
           android:layout_height="match_parent"
           android:scaleType="fitXY" />

答案 9 :(得分:4)

编辑 Jarno Argillanders 回答:

如何使用宽度和高度拟合图像:

1)初始化ImageView并设置Image:

iv = (ImageView) findViewById(R.id.iv_image);
iv.setImageBitmap(image);

2)现在调整大小:

scaleImage(iv);

已编辑的scaleImage方法:(您可以替换预期的边界值

private void scaleImage(ImageView view) {
    Drawable drawing = view.getDrawable();
    if (drawing == null) {
        return;
    }
    Bitmap bitmap = ((BitmapDrawable) drawing).getBitmap();

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int xBounding = ((View) view.getParent()).getWidth();//EXPECTED WIDTH
    int yBounding = ((View) view.getParent()).getHeight();//EXPECTED HEIGHT

    float xScale = ((float) xBounding) / width;
    float yScale = ((float) yBounding) / height;

    Matrix matrix = new Matrix();
    matrix.postScale(xScale, yScale);

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

    view.setImageDrawable(result);

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

和.xml:

<ImageView
    android:id="@+id/iv_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" />

答案 10 :(得分:3)

这适用于我的情况。

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

答案 11 :(得分:1)

我需要一个ImageView和一个Bitmap,所以Bitmap缩放到ImageView大小,ImageView的大小与缩放的Bitmap相同:)。

我正在浏览这篇文章,了解如何做到这一点,最后做了我想做的事,而不是这里描述的方式。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/acpt_frag_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/imageBackground"
android:orientation="vertical">

<ImageView
    android:id="@+id/acpt_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    android:layout_margin="@dimen/document_editor_image_margin"
    android:background="@color/imageBackground"
    android:elevation="@dimen/document_image_elevation" />

然后在onCreateView方法

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_scanner_acpt, null);

    progress = view.findViewById(R.id.progress);

    imageView = view.findViewById(R.id.acpt_image);
    imageView.setImageBitmap( bitmap );

    imageView.getViewTreeObserver().addOnGlobalLayoutListener(()->
        layoutImageView()
    );

    return view;
}

然后layoutImageView()代码

private void layoutImageView(){

    float[] matrixv = new float[ 9 ];

    imageView.getImageMatrix().getValues(matrixv);

    int w = (int) ( matrixv[Matrix.MSCALE_X] * bitmap.getWidth() );
    int h = (int) ( matrixv[Matrix.MSCALE_Y] * bitmap.getHeight() );

    imageView.setMaxHeight(h);
    imageView.setMaxWidth(w);

}

结果是图像完美贴合内部,保持纵横比, 当位图在里面时,没有来自ImageView的额外剩余像素。

Result

ImageView非常重要 wrap_content和adjustViewBounds为true, 然后setMaxWidth和setMaxHeight将起作用,这是用ImageView的源代码编写的,

/*An optional argument to supply a maximum height for this view. Only valid if
 * {@link #setAdjustViewBounds(boolean)} has been set to true. To set an image to be a
 * maximum of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
 * adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
 * layout params to WRAP_CONTENT. */

答案 12 :(得分:0)

我需要在Picasso的约束布局中完成这项工作,所以我将上述一些答案汇总在一起并提出了这个解决方案(我已经知道我正在加载的图像的宽高比,这样有帮助) :

在setContentView(...)之后的某个地方调用我的活动代码

protected void setBoxshotBackgroundImage() {
    ImageView backgroundImageView = (ImageView) findViewById(R.id.background_image_view);

    if(backgroundImageView != null) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int width = displayMetrics.widthPixels;
        int height = (int) Math.round(width * ImageLoader.BOXART_HEIGHT_ASPECT_RATIO);

        // we adjust the height of this element, as the width is already pinned to the parent in xml
        backgroundImageView.getLayoutParams().height = height;

        // implement your Picasso loading code here
    } else {
        // fallback if no element in layout...
    }
}

在我的XML

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp">

    <ImageView
        android:id="@+id/background_image_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitStart"
        app:srcCompat="@color/background"
        android:adjustViewBounds="true"
        tools:layout_editor_absoluteY="0dp"
        android:layout_marginTop="0dp"
        android:layout_marginBottom="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginLeft="0dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- other elements of this layout here... -->

</android.support.constraint.ConstraintLayout>

请注意缺少constraintBottom_toBottomOf属性。 ImageLoader 是我自己的静态类,用于图像加载util方法和常量。

答案 13 :(得分:0)

我正在使用一个非常简单的解决方案。这是我的代码:

imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.getLayoutParams().height = imageView.getLayoutParams().width;
imageView.setMinimumHeight(imageView.getLayoutParams().width);

我的图片被动态添加到gridview中。对imageview进行这些设置后,图片可以1:1比例自动显示。

答案 14 :(得分:0)

使用简单数学来调整图像大小。您可以调整ImageView的大小,也可以调整ImageView上设置的可绘制图像的大小。找到要在ImageView上设置的位图的宽度和高度,然后调用所需的方法。假设您的宽度500比高度大于调用方法

//250 is the width you want after resize bitmap
Bitmat bmp = BitmapScaler.scaleToFitWidth(bitmap, 250) ;
ImageView image = (ImageView) findViewById(R.id.picture);
image.setImageBitmap(bmp);

您可以使用此类来调整位图的大小。

public class BitmapScaler{
// Scale and maintain aspect ratio given a desired width
// BitmapScaler.scaleToFitWidth(bitmap, 100);
 public static Bitmap scaleToFitWidth(Bitmap b, int width)
  {
    float factor = width / (float) b.getWidth();
    return Bitmap.createScaledBitmap(b, width, (int) (b.getHeight() * factor), true);
  }


  // Scale and maintain aspect ratio given a desired height
  // BitmapScaler.scaleToFitHeight(bitmap, 100);
  public static Bitmap scaleToFitHeight(Bitmap b, int height)
  {
    float factor = height / (float) b.getHeight();
    return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
   }
 }

xml代码是

<ImageView
android:id="@+id/picture"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:adjustViewBounds="true"
android:scaleType="fitcenter" />

答案 15 :(得分:0)

如果它不适合您,则将android:background替换为android:src

android:src将发挥主要作用

&

它像魅惑般运转正常

enter image description here

答案 16 :(得分:0)

快速解答:

"rules": { "no-console": "off",}