Get the displayed size of an image inside an ImageView
Asked Answered
U

4

21

The code is simple:

<ImageView android:layout_width="fill_parent"
           android:layout_height="fill_parent"
           android:src="@drawable/cat"/>

Notice the ImageView used fill_parent for width and height.

The image cat is a small image and it will be zoomed in to fit the ImageView, and keep the width/height ratio at the same time.

My question is how to get the displayed size of the image? I tried:

imageView.getDrawable().getIntrinsicHeight()

But which it the original height of the image cat.

I tried:

imageView.getDrawable().getBounds()

But which returns Rect(0,0,0,0).

Underbred answered 17/9, 2012 at 16:9 Comment(4)
you can use ViewTreeObserver to get the real dimensions of any view at run time developer.android.com/reference/android/view/…Defeasible
Thanks, I'm looking at it. PS: is it the best/only way to get the size?Underbred
Sorry, even with ViewTreeObserver, I still don't know how to get the displayed size of the image.Underbred
possible duplicate of Trying to get the display size of an image in an ImageViewGrimaldo
T
56

the following will work:

ih=imageView.getMeasuredHeight();//height of imageView
iw=imageView.getMeasuredWidth();//width of imageView
iH=imageView.getDrawable().getIntrinsicHeight();//original height of underlying image
iW=imageView.getDrawable().getIntrinsicWidth();//original width of underlying image

if (ih/iH<=iw/iW) iw=iW*ih/iH;//rescaled width of image within ImageView
else ih= iH*iw/iW;//rescaled height of image within ImageView

(iw x ih) now represents the actual rescaled (width x height) for the image within the view (in other words the displayed size of the image)


EDIT: I think a nicer way to write the above answer (and one that works with ints) :

final int actualHeight, actualWidth;
final int imageViewHeight = imageView.getHeight(), imageViewWidth = imageView.getWidth();
final int bitmapHeight = ..., bitmapWidth = ...;
if (imageViewHeight * bitmapWidth <= imageViewWidth * bitmapHeight) {
    actualWidth = bitmapWidth * imageViewHeight / bitmapHeight;
    actualHeight = imageViewHeight;
} else {
    actualHeight = bitmapHeight * imageViewWidth / bitmapWidth;
    actualWidth = imageViewWidth;
}

return new Point(actualWidth,actualHeight);
Trevortrevorr answered 10/11, 2012 at 1:51 Comment(9)
don't forget about dividing int with int will result int. :)Gentianella
How to get the bitmapHeight and bitmapWidth. I mean from where we can get the bitmap and how.Shrunken
@androiddeveloper: I am not getting correct height of Image in ImageViewFirearm
@androiddeveloper How to get bitmapHeight and bitmapWidth as per your edited answer?Firearm
@PragyaMendiratta It's a part of the input. You have a bitmap you wish to set to the ImageView, so you can get its size, using getWidth and getHeight : developer.android.com/reference/android/graphics/… developer.android.com/reference/android/graphics/…Mickelson
hi @androiddeveloper,what if the image size is 200X50 and imageView with 100X100,then what will be the image's dimension by using the method u just suggested, and one more thing the imageView is set to adjustViewBound=true??Bellhop
@NirmalPrajapat I wrote it a long time ago. I don't remember. Try it.Mickelson
getWidth and getHeight will give Imageview height and width ?@androiddeveloperFirearm
Oh thanks, God. You doing great.Bangs
R
8

Here is a helper function to get the bounds of image in an imageView.

/**
 * Helper method to get the bounds of image inside the imageView.
 *
 * @param imageView the imageView.
 * @return bounding rectangle of the image.
 */
public static RectF getImageBounds(ImageView imageView) {
    RectF bounds = new RectF();
    Drawable drawable = imageView.getDrawable();
    if (drawable != null) {
        imageView.getImageMatrix().mapRect(bounds, new RectF(drawable.getBounds()));
    }
    return bounds;
}
Reactant answered 4/7, 2017 at 6:0 Comment(0)
S
0

I guess a lot of people are coming from this example https://developer.android.com/training/animation/zoom.html and don't want to use android:scaleType="centerCrop" (maybe because the ImageView is in a constraint layout and you want to see the small picture uncroped) don't you worry, I got your back!

Just replace the entire block beginning with

// Adjust the start bounds to be the same aspect ratio as the final
// bounds using the "center crop" technique.

with the following

//adjust for scaled image to constraint
int realheight = ResourcesCompat.getDrawable(getResources(),imageResId,null).getIntrinsicHeight();
int realwidth = ResourcesCompat.getDrawable(getResources(),imageResId,null).getIntrinsicWidth();

// Adjust the start bounds to be the same aspect ratio as the final
// bounds using ueen's adjusteddimensions technique. This prevents undesirable
// stretching during the animation. Also calculate the start scaling
// factor (the end scaling factor is always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
        > (float) startBounds.width() / startBounds.height()) {
    // Extend start bounds horizontally
    // after check whether height or width needs adjusting
    if ((float) startBounds.width() / startBounds.height() < (float) realwidth / realheight) {
        int adjustedheight = realheight*startBounds.width()/realwidth;
        int adjustedoffset = (startBounds.height()-adjustedheight) / 2;
        startScale = (float) adjustedheight / finalBounds.height();
        float startWidth = startScale * finalBounds.width();
        float deltaWidth = (startWidth - startBounds.width()) / 2;
        startBounds.left -= deltaWidth;
        startBounds.right += deltaWidth;
        startBounds.offset(+0, +adjustedoffset);
    } else {
        int adjustedwidth = realwidth*startBounds.height()/realheight;
        int adjustedoffset = (startBounds.width()-adjustedwidth) / 2;
        startScale = (float) startBounds.height() / finalBounds.height();
        float startWidth = startScale * finalBounds.width();
        float deltaWidth = (startWidth - adjustedwidth) / 2;
        startBounds.left -= deltaWidth;
        startBounds.right += deltaWidth;
        startBounds.offset(+adjustedoffset, +0);
    }
} else {
    // Extend start bounds vertically
    // after check whether height or width needs adjusting
    if ((float) startBounds.width() / startBounds.height() > (float) realwidth / realheight) {
        int adjustedwidth = realwidth*startBounds.height()/realheight;
        int adjustedoffset = (startBounds.width()-adjustedwidth) / 2;
        startScale = (float) adjustedwidth / finalBounds.width();
        float startHeight = startScale * finalBounds.height();
        float deltaHeight = (startHeight - startBounds.height()) / 2;
        startBounds.top -= deltaHeight;
        startBounds.bottom += deltaHeight;
        startBounds.offset(+adjustedoffset, +0);
    } else {
        int adjustedheight = realheight*startBounds.width()/realwidth;
        int adjustedoffset = (startBounds.height()-adjustedheight) / 2;
        startScale = (float) startBounds.width() / finalBounds.width();
        float startHeight = startScale * finalBounds.height();
        float deltaHeight = (startHeight - adjustedheight) / 2;
        startBounds.top -= deltaHeight;
        startBounds.bottom += deltaHeight;
        startBounds.offset(+0, +adjustedoffset);
    }
}

works like a charme, you're welcome :)

Further explanation: as usual we check wheter the picture is taller than wide (expanded the height of the picture should match the height of expandedImageView) or vice versa. Then we check if the picture in the original (smaller) ImageView (thumbView) is matching the width or the heigth, so we can adjust for the space. This way we achieve a smooth scaling animation while not croping the picture in the thumbView, no matter it's dimension (as they may change from device to device when using constarints) or that of the picture.

Stearn answered 14/5, 2019 at 15:28 Comment(1)
Actually, I am coming from an OCR library that returns the placements of words relative to the original image and I have to position them on a scaled ImageView. Your origin story was nice, though.Pinch
M
-1

use

// For getting imageview height
imgObj.getMeasuredHeight()


// For getting imageview width
imgObj.getMeasuredWidth();


//For getting image height inside ImageView
 imgObj.getDrawable().getIntrinsicHeight();


//For getting image width inside ImageView
 imgObj.getDrawable().getIntrinsicWidth();
Mayfair answered 17/9, 2012 at 16:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.