Get the displayed size of an image inside an ImageView

后端 未结 4 843
时光取名叫无心
时光取名叫无心 2020-12-01 04:47

The code is simple:



        
相关标签:
4条回答
  • 2020-12-01 05:32

    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();
    
    0 讨论(0)
  • 2020-12-01 05:33

    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);
    
    0 讨论(0)
  • 2020-12-01 05:33

    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;
    }
    
    0 讨论(0)
  • 2020-12-01 05:39

    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.

    0 讨论(0)
提交回复
热议问题