0

Let's assume that the size of the image of this beautiful mushroom, that I took the other day, is unknown. It could be 350x500 pixels or 1080x1920 or 1920x1080 or 1x1. Any image should be able to used here.

What I'm trying to accomplish is this: I need to stretch the image all the way in the directions where it would meet the edge of the parent view sooner, but not occupy any area in the other two directions.

So here's an example: I have a vertical image and I need to display it on a tablet. In this case it would need to be stretched (as well as maintain aspect ratio) up and down, but not left and right. It is important that the black area on left and right is unoccupied. It should look like this: enter image description here

The same image would need to be stretched left and right, but not up and down, if it is wider than the parent view:

enter image description here

Here's what I tried:

  1. Setting xml layout_width and layout_height attributes to different combinations of match_parent and wrap_content. That didn't work because we cannot be sure how to stretch the image at compile time because we don't have the dimentions of the image, nor the dimentions of the container.

  2. Tried to programmatically stretch the bitmap like this, but that only stretches the width, and is a little inefficient.

It would be nice if there was a way to do it by adjusting the LayoutParams of the ImageView programmatically, based on how the image ratio compares with the parent container ratio. Does anyone know of a clean way to do that?

Community
  • 1
  • 1
Oleksiy
  • 37,477
  • 22
  • 74
  • 122
  • Did you try scale type CENTER_INSIDE? See http://developer.android.com/reference/android/widget/ImageView.ScaleType.html – Henry Oct 15 '14 at 19:23
  • So you are saying that an `imageView.setScaleType(ScaleType.CENTER_INSIDE)` or `ScaleType.CROP` for the view would not suffice because you are trying to do some sophisticated decision making in the process? – Jay Snayder Oct 15 '14 at 19:23
  • @Henry `center_inside` does not stretch the image at all if the image is too small. If I use `wrap_content`, it will keep the image its original size. If I use `match_parent`, it will still keep the image its original size, even though the view occupying the whole parent. – Oleksiy Oct 15 '14 at 19:39
  • @JaySnayder Do you mean `ScaleType.CENTER_CROP`? I don't want to crop it. I want to keep all of it inside and keep the aspect ratio the same. I explained why `CENTER_INSIDE` won't work in the comment above – Oleksiy Oct 15 '14 at 19:40
  • @Oleksiy Sorry I had meant `ScaleTYPE.CENTER`. By definition that one should fill one direction while maintaining aspect ratio if you have `match_parent` assigned as the `ImageView` size. However, perhaps I am still misinterpreting the question. I thought that was what you were aiming for. – Jay Snayder Oct 15 '14 at 20:13
  • @JaySnayder `ScaleTYPE.CENTER` centers the image in the view, but performs no scaling. I need it to scale uniformly – Oleksiy Oct 15 '14 at 20:16
  • @Oleksiy Hrm. Interesting. It did scale uniformly with a quick test for me on my end. If you are doing it programmatically, you might need to do `adjustViewBounds(true)` on the `ImageView`. Good luck. – Jay Snayder Oct 16 '14 at 13:01

1 Answers1

0

I think there is not an out of the box ScaleType mechanism for this. You will need to determine yours and use the Matrix class to scale it.

This is the code that I used to get the cover photo of the attached image to show with my custom ScaleType

int boundBoxSize = getResources().getDimensionPixelSize(R.dimen.user_profile_avatar_size);
int border = getResources().getDimensionPixelSize(R.dimen.user_profile_avatar_border);

Drawable drawing = imageView.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();

int width = bitmap.getWidth();
int height = bitmap.getHeight();

float xScale = ((float) boundBoxSize)/width;
float yScale = ((float) boundBoxSize)/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);
width = scaledBitmap.getWidth();
height = scaledBitmap.getHeight();
imageView.setImageBitmap(scaledBitmap);

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.width = width + (2*border);
layoutParams.height = height + (2*border);

imageView.setLayoutParams(layoutParams);
imageView.setBackgroundColor(getResources().getColor(R.color.image_border));
imageView.setPadding(border, border, border, border);

enter image description here

Amilcar Andrade
  • 1,131
  • 9
  • 16