47

我正在尝试获取图像视图中显示的图像的实际大小。实际上我的图像比屏幕大,并且图像视图正在调整图像大小以显示它。我正在寻找这个新尺寸。

我试图在自定义视图中覆盖 ImageView 的 onDraw 方法,但我没有得到正确的高度和宽度......

public class LandImageView extends ImageView
{
    public LandImageView( Context context )
    {
        super( context );
    }

    public LandImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public LandImageView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw( Canvas canvas )
    {
        super.onDraw( canvas );

        int test = this.getWidth();
        int test2 = this.getHeight();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

你有什么线索吗?

4

14 回答 14

106

这里的答案都没有真正回答这个问题:

Bitmapan 显示的任何尺寸的a 中ImageView,找到显示图像的实际尺寸,而不是提供的尺寸Bitmap

即:

  • 使用ImageView.getDrawable().getInstrinsicWidth()andgetIntrinsicHeight()都将返回原始尺寸。
  • Drawable通过并将ImageView.getDrawable()其转换为 a BitmapDrawable,然后使用BitmapDrawable.getBitmap().getWidth()getHeight()返回原始图像及其尺寸。

获得显示图像的实际尺寸的唯一方法是提取并使用Matrix用于显示图像的变换。这必须在测量阶段之后完成,这里的示例显示它在自定义Override中调用:onMeasure()ImageView

public class SizeAwareImageView extends ImageView {

    public SizeAwareImageView(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // Get image matrix values and place them in an array
        float[] f = new float[9];
        getImageMatrix().getValues(f);

        // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
        final float scaleX = f[Matrix.MSCALE_X];
        final float scaleY = f[Matrix.MSCALE_Y];

        // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
        final Drawable d = getDrawable();
        final int origW = d.getIntrinsicWidth();
        final int origH = d.getIntrinsicHeight();

        // Calculate the actual dimensions
        final int actW = Math.round(origW * scaleX);
        final int actH = Math.round(origH * scaleY);

        Log.e("DBG", "["+origW+","+origH+"] -> ["+actW+","+actH+"] & scales: x="+scaleX+" y="+scaleY);
    }

}  

注意:要从一般代码中获取图像转换Matrix(如在 an 中Activity),该函数是ImageView.getImageMatrix()- 例如myImageView.getImageMatrix()

于 2013-03-21T03:16:54.317 回答
27

我扩展了 B T 的答案以从中生成一个静态方法,并将图像左侧和顶部位置包含到 ImageView 中:

/**
 * Returns the bitmap position inside an imageView.
 * @param imageView source ImageView
 * @return 0: left, 1: top, 2: width, 3: height
 */
public static int[] getBitmapPositionInsideImageView(ImageView imageView) {
    int[] ret = new int[4];

    if (imageView == null || imageView.getDrawable() == null)
        return ret;

    // Get image dimensions
    // Get image matrix values and place them in an array
    float[] f = new float[9];
    imageView.getImageMatrix().getValues(f);

    // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
    final float scaleX = f[Matrix.MSCALE_X];
    final float scaleY = f[Matrix.MSCALE_Y];

    // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
    final Drawable d = imageView.getDrawable();
    final int origW = d.getIntrinsicWidth();
    final int origH = d.getIntrinsicHeight();

    // Calculate the actual dimensions
    final int actW = Math.round(origW * scaleX);
    final int actH = Math.round(origH * scaleY);

    ret[2] = actW;
    ret[3] = actH;

    // Get image position
    // We assume that the image is centered into ImageView
    int imgViewW = imageView.getWidth();
    int imgViewH = imageView.getHeight();

    int top = (int) (imgViewH - actH)/2;
    int left = (int) (imgViewW - actW)/2;

    ret[0] = left;
    ret[1] = top;

    return ret;
}
于 2014-11-14T13:19:42.240 回答
11

我发现 WarrenFaith 关于使用 setAdjustViewBounds 的建议有效,但我不得不将 ImageView 的 layout_width/layout_height 更改为 'wrap_content'(使用 'match_parent',setAdjustViewBounds 什么也没做)。为了获得我想要的高度/宽度/重力行为,我必须将 ImageView 包装在 FrameLayout 中:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true"
        />
</FrameLayout>

完成此操作后,ImageView 的尺寸(由 getWidth() 和 getHeight() 返回)与图像的显示尺寸相匹配。

于 2013-03-07T03:13:29.963 回答
6

尝试

ImageView.getDrawable().getIntrinsicHeight()
ImageView.getDrawable().getIntrinsicWidth()
于 2010-10-23T19:18:43.480 回答
1

我只是路过,但希望它仍然有助于我假设您在 imageView 中谈论位图

你想了解的是两者的区别

bmpBack.getWidth() -> 这给你你的位图的大小和 bmpBack.getScaledWidth(canvas); -> 这将为您提供屏幕上显示的位图大小。

我从未使用过 ImageView,因为相对显示让我发疯,所以最后我只是覆盖了 onDraw,并且我的画布与 opengl 非常相似。

我认为这是你的问题

干杯

杰森

于 2010-10-26T06:43:26.207 回答
1

您可以使用 imageview 的 viewtreeobserver 和 addonDrawListener。

ViewTreeObserver vto = imageView.getViewTreeObserver();
    vto.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
        @Override
        public void onDraw() {

            float[] f = new float[9];
            imageView.getImageMatrix().getValues(f);

            // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
            final float scaleX = f[Matrix.MSCALE_X];
            final float scaleY = f[Matrix.MSCALE_Y];


            // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
            final Drawable d = imageView. getDrawable();
            final int origW = d.getIntrinsicWidth();
            final int origH = d.getIntrinsicHeight();

            // Calculate the actual dimensions
            final int actW = Math.round(origW * scaleX);
            final int actH = Math.round(origH * scaleY);

        }
    });
于 2018-06-21T05:05:32.127 回答
0
public class images extends Activity {
ImageView i1;
LinearLayout l1;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
     i1=(ImageView)findViewById(R.id.iv);
     l1 = new LinearLayout(this);
    ImageView i = new ImageView(this);
    ImageView i1 = new ImageView(this);
    i.setImageResource(R.drawable.  imagename.........);

    l1.addView(i);
    l1.addView(i1);
    setContentView(l1);
    }
}

首先在你的资源文件夹中添加图像......并在 xml 文件中创建一个图像视图......

于 2010-11-10T09:02:53.280 回答
0

我正在寻找一种解决方案,将图像视图的尺寸设置为缩放图像,以防止顶部/底部或左侧/右侧出现空白空间(因为视图的尺寸不会改变以适应缩放图像)。

我发现解决问题的方法是使用mImageView.setAdjustViewBounds(true);导致正确布局尺寸的方法。我没有缩放的图像尺寸,但我得到了我正在寻找的结果......如果有人需要它......

于 2011-03-09T14:31:59.790 回答
0

如果我理解正确,您需要您的 ImageView 尺寸,以便相应地缩放您的图像。我用一个自定义类做到了这一点,我在其中覆盖了onMeasure()获取宽度和高度的调用。

class LandImageView extends ImageView{ 
public LandImageView (Context context, AttributeSet attrs) {
  super (context, attrs);
 } 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
 {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);

  final int width = MeasureSpec.getSize(widthMeasureSpec);
  final int height = MeasureSpec.getSize(heightMeasureSpec);

  Log.v("", String.format("w %d h %d", width, height));
                // width and height are the dimensions for your image
                // you should remember the values to scale your image later on

  this.setMeasuredDimension(width, height );
 }}

在 onMeasure 中,您可以获得图像的宽度和高度,以使其适合您的视图。

您可以像这样在布局中使用 LandImageView:

<my.package.LandImageView ... >
于 2010-10-24T10:50:16.137 回答
0

尝试使用带有 BitmapFactory.Options() 类的BitmapFactory.decodeResource (Resources res, int id, BitmapFactory.Options opts)加载您的资源。BitmapFactory.Options()有一个名为“inJustDecodeBounds”的标志,只给出资源维度。

希望有帮助。

于 2010-10-24T12:10:22.690 回答
0

尝试覆盖onMeasure(int widthMeasureSpec, int heightMeasureSpec)而不是 onSizeChanged。

于 2010-10-04T13:16:35.383 回答
0

我认为你需要在屏幕上可见的图像大小,因为你只需要这样做:

@Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        initialWidth = this.getMeasuredWidth();
        initialHeight = this.getMeasuredHeight();
    }

并请查看以下方法的文档:getWidht(), getHeight(), getMeasuredWidth(),getMeasuredHeight()等。您将了解它为您提供的大小。

编辑:如果您想要将实际widthheight图像加载到imageView. 您可能希望将方法调用从getMeasuredWidth()togetIntrinsicWidth()getMeasuredHeight()to更改为getIntrinsicHeight()

  Drawable drawable = getDrawable();
  actualWidth = drawable.getIntrinsicWidth();
  actualHeight = drawable.getIntrinsicHeight();
于 2017-12-25T06:26:36.233 回答
0

只需使用此代码(在活动中):

@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
    super.onWindowFocusChanged(hasWindowFocus);
    final ImageView imageView = findViewById(R.id.imageView);
    int width = imageView.getWidth(), height = imageView.getHeight();
}

如果图片到达 imageView 的末端。

于 2019-07-25T01:01:21.317 回答
-1

ImageView.getBackground() 或 ImageView.getDrawable(),然后 Drawable.getBounds() 怎么样?

于 2010-10-21T20:25:33.187 回答