获取 ImageView 中图像的显示大小
Posted
技术标签:
【中文标题】获取 ImageView 中图像的显示大小【英文标题】:Get the displayed size of an image inside an ImageView 【发布时间】:2012-09-09 21:34:58 【问题描述】:代码很简单:
<ImageView android:layout_
android:layout_
android:src="@drawable/cat"/>
注意 ImageView 使用 fill_parent
表示宽度和高度。
图片cat
是一个小图片,它会被放大以适应ImageView,同时保持宽高比。
我的问题是如何获得图像的显示尺寸?我试过了:
imageView.getDrawable().getIntrinsicHeight()
但它是图片的原始高度cat
。
我试过了:
imageView.getDrawable().getBounds()
但它返回Rect(0,0,0,0)
。
【问题讨论】:
您可以使用 ViewTreeObserver 在运行时获取任何视图的真实尺寸developer.android.com/reference/android/view/… 谢谢,我正在看。 PS:这是获得尺寸的最佳/唯一方法吗? 对不起,即使使用 ViewTreeObserver,我仍然不知道如何获取图像的显示大小。 Trying to get the display size of an image in an ImageView的可能重复 【参考方案1】:使用
// 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();
【讨论】:
【参考方案2】:以下将起作用:
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) 现在表示视图中图像的实际重新缩放(宽度 x 高度)(换句话说,图像的显示大小)
编辑:我认为编写上述答案的更好方法(以及与整数一起使用的答案):
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);
【讨论】:
不要忘记将 int 与 int 相除将得到 int。 :) 如何获取bitmapHeight和bitmapWidth。我的意思是我们可以从哪里获得位图以及如何获得。 @androiddeveloper:我在 ImageView 中没有得到正确的图像高度 @androiddeveloper 如何根据您编辑的答案获取 bitmapHeight 和 bitmapWidth? 嗨@androiddeveloper,如果图像大小是200X50,imageView 是100X100,那么使用你刚才建议的方法,图像的尺寸是多少,还有一件事是imageView 设置为@987654323 @??【参考方案3】:这是一个辅助函数,用于获取 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;
【讨论】:
【参考方案4】:我猜很多人都来自这个例子https://developer.android.com/training/animation/zoom.html,不想使用android:scaleType="centerCrop"
(可能是因为ImageView处于约束布局,你想看到未裁剪的小图片)不要你担心,我支持你!
只需替换以
开头的整个块// Adjust the start bounds to be the same aspect ratio as the final
// bounds using the "center crop" technique.
以下
//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);
像魅力一样工作, 不客气:)
进一步解释:像往常一样,我们检查图片是否高于宽度(展开后图片的高度应与expandedImageView的高度匹配),反之亦然。然后我们检查原始(较小)ImageView(thumbView)中的图片是否匹配宽度或高度,以便我们可以调整空间。 通过这种方式,我们实现了平滑的缩放动画,而无需在 thumbView 中裁剪图片,无论它的尺寸(因为使用约束时它们可能会因设备而异)或图片的尺寸。
【讨论】:
实际上,我来自一个 OCR 库,它返回单词相对于原始图像的位置,我必须将它们定位在缩放的ImageView
上。不过,你的起源故事很不错。以上是关于获取 ImageView 中图像的显示大小的主要内容,如果未能解决你的问题,请参考以下文章