匹配图像到ImageView,保持纵横比,然后调整ImageView的图像尺寸?

时间:2022-08-27 10:46:56

How to fit an image of random size to an ImageView?
When:

如何将随机大小的图像匹配到ImageView?当:

  • Initially ImageView dimensions are 250dp * 250dp
  • 最初,ImageView维数是250dp * 250dp。
  • The image's larger dimension should be scaled up/down to 250dp
  • 图像的大尺寸应该放大/缩小到250dp。
  • The image should keep its aspect ratio
  • 图像应该保持纵横比。
  • The ImageView dimensions should match scaled image's dimensions after scaling
  • 在缩放后,ImageView维度应该匹配缩放图像的维度。

E.g. for an image of 100*150, the image and the ImageView should be 166*250.
E.g. for an image of 150*100, the image and the ImageView should be 250*166.

例如,对于100*150的图像,图像和ImageView应该是166*250。例如,对于150*100的图像,图像和ImageView应该是250*166。

If I set the bounds as

如果我把边界设为。

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

images fit properly in the ImageView, but the ImageView is always 250dp * 250dp.

图像在ImageView中很合适,但是ImageView总是250dp * 250dp。

13 个解决方案

#1


124  

(The answer was heavily modified after clarifications to the original question)

(在对最初的问题进行了澄清之后,答案被严重修改了)

After clarifications:
This cannot be done in xml only. It is not possible to scale both the image and the ImageView so that image's one dimension would always be 250dp and the ImageView would have the same dimensions as the image.

在澄清之后:这不能只在xml中完成。不可能对图像和图像视图进行缩放,这样图像的一维永远是250dp,而ImageView与图像具有相同的维度。

This code scales Drawable of an ImageView to stay in a square like 250dp x 250dp with one dimension exactly 250dp and keeping the aspect ratio. Then the ImageView is resized to match the dimensions of the scaled image. The code is used in an activity. I tested it via button click handler.

这段代码可以缩放一个ImageView,以保持在一个像250dp x 250dp这样的正方形中,一个维度正好是250dp,并且保持纵横比。然后,ImageView调整大小以匹配缩放图像的大小。代码用于活动。我通过按钮点击处理程序测试了它。

Enjoy. :)

享受。:)

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

The xml code for the ImageView:

ImageView的xml代码:

<ImageView a:id="@+id/image_box"
    a:background="#ff0000"
    a:src="@drawable/star"
    a:layout_width="wrap_content"
    a:layout_height="wrap_content"
    a:layout_marginTop="20dp"
    a:layout_gravity="center_horizontal"/>


Thanks to this discussion for the scaling code:
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

感谢这个关于扩展代码的讨论:http://www.anddev.org/resize_and_rotate_image_-_example-t621.html。


UPDATE 7th, November 2012:
Added null pointer check as suggested in comments

更新7,2012年11月:在评论中添加空指针检查。

#2


191  

May not be answer for this specific question, but if someone is, like me, searching for answer how to fit image in ImageView with bounded size (for example, maxWidth) while preserving Aspect Ratio and then get rid of excessive space occupied by ImageView, then the simplest solution is to use the following properties in XML:

可能不会回答这个特定的问题,但如果有人像我一样,在寻找答案如何适应图像与有界ImageView大小(例如,maxWidth),同时保留长宽比,然后摆脱过度ImageView占用的空间,那么最简单的解决方案是使用XML的以下属性:

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

#3


29  

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

#4


18  

The Below code make the bitmap perfectly with same size of the imageview. Get the bitmap image height and width and then calculate the new height and width with the help of imageview's parameters. That give you required image with best aspect ratio.

下面的代码使位图与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)

enjoy.

享受。

#5


14  

try adding android:scaleType="fitXY" to your ImageView.

尝试添加android:scaleType="fitXY"到你的ImageView。

#6


7  

After searching for a day, I think this is the easiest solution:

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

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

#7


4  

Use this code:

使用这段代码:

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

#8


4  

this can all be done using XML... the other methods seem pretty complicated. Anyway, you just set the height to what ever you want in dp, then set the width to wrap content or visa versa. Use scaleType fitCenter to adjust the size of the image.

这一切都可以用XML来完成……其他方法看起来相当复杂。不管怎样,你只要把高度设置成你想要的dp,然后设置宽度来包装内容,或者反过来。使用scaleType fitCenter调整图像的大小。

<ImageView
    android:layout_height="200dp"
    android:layout_width="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"
    android:src="@mipmap/ic_launcher"
    android:layout_below="@+id/title"
    android:layout_margin="5dip"
    android:id="@+id/imageView1">

#9


4  

Edited Jarno Argillanders answer:

How to fit Image with your Width and Height:

1) Initialize ImageView and set Image:

编辑Jarno Argillanders回答:如何将图像与宽度和高度匹配:1)初始化ImageView和set Image:

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

2) Now resize:

2)现在调整:

scaleImage(iv);

Edited scaleImage method: (you can replace EXPECTED bounding values)

编辑的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);
}

And .xml:

和xml:

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

#10


3  

The Best solution that works in most cases is

在大多数情况下,最好的解决方案是。

Here is an example:

这是一个例子:

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

#11


1  

This did it for my case.

这是为了我的案子。

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

#12


0  

I needed to get this done in a constraint layout with Picasso, so I munged together some of the above answers and came up with this solution (I already know the aspect ratio of the image I'm loading, so that helps):

我需要在与毕加索的约束布局中完成这一操作,所以我把上面的一些答案拼凑在一起,并提出了这个解决方案(我已经知道我正在加载的图像的纵横比,这很有帮助):

Called in my activity code somewhere after setContentView(...)

在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...
    }
}

In my XML

在我的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>

Note the lack of a constraintBottom_toBottomOf attribute. ImageLoader is my own static class for image loading util methods and constants.

注意,缺少一个约束的底部的属性。ImageLoader是我自己的静态类,用于加载util方法和常量。

#13


0  

I needed to have an ImageView and an Bitmap, so the Bitmap is scaled to ImageView size, and size of the ImageView is the same of the scaled Bitmap :).

我需要一个ImageView和一个位图,所以位图被缩放到ImageView的大小,而ImageView的大小和缩放的位图是一样的。

I was looking through this post for how to do it, and finally did what I want, not the way described here though.

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

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

and then in onCreateView method

然后在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;
}

and then layoutImageView() code

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

}

And the result is that image fits inside perfectly, keeping aspect ratio, and doesn't have extra leftover pixels from ImageView when the Bitmap is inside.

结果是,图像在完美的内部,保持纵横比,当位图在里面时,图像视图中没有多余的像素。

Result

结果

It's important ImageView to have wrap_content and adjustViewBounds to true, then setMaxWidth and setMaxHeight will work, this is written in the source code of ImageView,

有一个重要的ImageView将wrap_content和readviewbounds设为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. */

#1


124  

(The answer was heavily modified after clarifications to the original question)

(在对最初的问题进行了澄清之后,答案被严重修改了)

After clarifications:
This cannot be done in xml only. It is not possible to scale both the image and the ImageView so that image's one dimension would always be 250dp and the ImageView would have the same dimensions as the image.

在澄清之后:这不能只在xml中完成。不可能对图像和图像视图进行缩放,这样图像的一维永远是250dp,而ImageView与图像具有相同的维度。

This code scales Drawable of an ImageView to stay in a square like 250dp x 250dp with one dimension exactly 250dp and keeping the aspect ratio. Then the ImageView is resized to match the dimensions of the scaled image. The code is used in an activity. I tested it via button click handler.

这段代码可以缩放一个ImageView,以保持在一个像250dp x 250dp这样的正方形中,一个维度正好是250dp,并且保持纵横比。然后,ImageView调整大小以匹配缩放图像的大小。代码用于活动。我通过按钮点击处理程序测试了它。

Enjoy. :)

享受。:)

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

The xml code for the ImageView:

ImageView的xml代码:

<ImageView a:id="@+id/image_box"
    a:background="#ff0000"
    a:src="@drawable/star"
    a:layout_width="wrap_content"
    a:layout_height="wrap_content"
    a:layout_marginTop="20dp"
    a:layout_gravity="center_horizontal"/>


Thanks to this discussion for the scaling code:
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

感谢这个关于扩展代码的讨论:http://www.anddev.org/resize_and_rotate_image_-_example-t621.html。


UPDATE 7th, November 2012:
Added null pointer check as suggested in comments

更新7,2012年11月:在评论中添加空指针检查。

#2


191  

May not be answer for this specific question, but if someone is, like me, searching for answer how to fit image in ImageView with bounded size (for example, maxWidth) while preserving Aspect Ratio and then get rid of excessive space occupied by ImageView, then the simplest solution is to use the following properties in XML:

可能不会回答这个特定的问题,但如果有人像我一样,在寻找答案如何适应图像与有界ImageView大小(例如,maxWidth),同时保留长宽比,然后摆脱过度ImageView占用的空间,那么最简单的解决方案是使用XML的以下属性:

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

#3


29  

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

#4


18  

The Below code make the bitmap perfectly with same size of the imageview. Get the bitmap image height and width and then calculate the new height and width with the help of imageview's parameters. That give you required image with best aspect ratio.

下面的代码使位图与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)

enjoy.

享受。

#5


14  

try adding android:scaleType="fitXY" to your ImageView.

尝试添加android:scaleType="fitXY"到你的ImageView。

#6


7  

After searching for a day, I think this is the easiest solution:

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

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

#7


4  

Use this code:

使用这段代码:

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

#8


4  

this can all be done using XML... the other methods seem pretty complicated. Anyway, you just set the height to what ever you want in dp, then set the width to wrap content or visa versa. Use scaleType fitCenter to adjust the size of the image.

这一切都可以用XML来完成……其他方法看起来相当复杂。不管怎样,你只要把高度设置成你想要的dp,然后设置宽度来包装内容,或者反过来。使用scaleType fitCenter调整图像的大小。

<ImageView
    android:layout_height="200dp"
    android:layout_width="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"
    android:src="@mipmap/ic_launcher"
    android:layout_below="@+id/title"
    android:layout_margin="5dip"
    android:id="@+id/imageView1">

#9


4  

Edited Jarno Argillanders answer:

How to fit Image with your Width and Height:

1) Initialize ImageView and set Image:

编辑Jarno Argillanders回答:如何将图像与宽度和高度匹配:1)初始化ImageView和set Image:

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

2) Now resize:

2)现在调整:

scaleImage(iv);

Edited scaleImage method: (you can replace EXPECTED bounding values)

编辑的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);
}

And .xml:

和xml:

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

#10


3  

The Best solution that works in most cases is

在大多数情况下,最好的解决方案是。

Here is an example:

这是一个例子:

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

#11


1  

This did it for my case.

这是为了我的案子。

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

#12


0  

I needed to get this done in a constraint layout with Picasso, so I munged together some of the above answers and came up with this solution (I already know the aspect ratio of the image I'm loading, so that helps):

我需要在与毕加索的约束布局中完成这一操作,所以我把上面的一些答案拼凑在一起,并提出了这个解决方案(我已经知道我正在加载的图像的纵横比,这很有帮助):

Called in my activity code somewhere after setContentView(...)

在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...
    }
}

In my XML

在我的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>

Note the lack of a constraintBottom_toBottomOf attribute. ImageLoader is my own static class for image loading util methods and constants.

注意,缺少一个约束的底部的属性。ImageLoader是我自己的静态类,用于加载util方法和常量。

#13


0  

I needed to have an ImageView and an Bitmap, so the Bitmap is scaled to ImageView size, and size of the ImageView is the same of the scaled Bitmap :).

我需要一个ImageView和一个位图,所以位图被缩放到ImageView的大小,而ImageView的大小和缩放的位图是一样的。

I was looking through this post for how to do it, and finally did what I want, not the way described here though.

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

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

and then in onCreateView method

然后在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;
}

and then layoutImageView() code

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

}

And the result is that image fits inside perfectly, keeping aspect ratio, and doesn't have extra leftover pixels from ImageView when the Bitmap is inside.

结果是,图像在完美的内部,保持纵横比,当位图在里面时,图像视图中没有多余的像素。

Result

结果

It's important ImageView to have wrap_content and adjustViewBounds to true, then setMaxWidth and setMaxHeight will work, this is written in the source code of ImageView,

有一个重要的ImageView将wrap_content和readviewbounds设为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. */