【问题标题】:How to get the position of a picture inside an ImageView?如何获取图片在 ImageView 中的位置?
【发布时间】:2013-04-24 13:26:55
【问题描述】:

我有一个不同尺寸的图片库。每个图像按顺序显示在ImageView 中(通过OnTouchListener)。我需要知道我向ImageView 展示亲戚的图片框架的位置,但是通过我所做的测试,我只得到了ImageView 的坐标。有什么想法吗?

我需要 (x1, y1) 和 (x2, y2) 的值。

提前致谢。

这是我的课:

public class PuzzleView extends ImageView {

protected Paint currentPaint;    

protected boolean drawRect = false;    
protected float left;
protected float top;
protected float right;
protected float bottom;

protected float pixelX;
protected float pixelY;

protected int nChunksX = 5;
protected int nChunksY = 5;

protected int currentWidth = 0;
protected int currentHeight = 0;

public PuzzleView(Context context, AttributeSet attrs) {
    super(context, attrs);

    currentPaint = new Paint();
    currentPaint.setDither(true);
    currentPaint.setColor(0xFF00CC00);  
    currentPaint.setStyle(Paint.Style.STROKE);
    currentPaint.setStrokeJoin(Paint.Join.ROUND);
    currentPaint.setStrokeCap(Paint.Cap.ROUND);
    currentPaint.setStrokeWidth(2);                           
}

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

    float chunkWidth = currentWidth / nChunksX;
    float chunkHeight = currentHeight / nChunksY;

    float posX = ((int)(pixelX / chunkWidth)) * chunkWidth;
    float posY = ((int)(pixelY / chunkHeight)) * chunkHeight;

    canvas.drawRect(posX, posY, posX + chunkWidth, posY + chunkHeight, currentPaint);

    Rect rect = this.getDrawable().getBounds();
    canvas.drawRect(rect, currentPaint);
}

@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);

    currentWidth = actW;
    currentHeight = actH;
}

public boolean isDrawRect() {
    return drawRect;
}

public void setDrawRect(boolean drawRect) {
    this.drawRect = drawRect;
}

public float getLeftRect() {
    return left;
}

public void setLeftRect(float left) {
    this.left = left;
}

public float getTopRect() {
    return top;
}

public void setTopRect(float top) {
    this.top = top;
}

public float getRightRect() {
    return right;
}

public void setRightRect(float right) {
    this.right = right;
}

public float getBottomRect() {
    return bottom;
}

public void setBottomRect(float bottom) {
    this.bottom = bottom;
}

public float getPixelX() {
    return pixelX;
}

public void setPixelX(float pixelX) {
    this.pixelX = pixelX;
}

public float getPixelY() {
    return pixelY;
}

public void setPixelY(float pixelY) {
    this.pixelY = pixelY;
}

public int getChunksX() {
    return nChunksX;
}

public void setChunksX(int nChunksX) {
    this.nChunksX = nChunksX;
}

public int getChunksY() {
    return nChunksY;
}

public void setChunksY(int nChunksY) {         
    this.nChunksY = nChunksY;
}
}

目前,源图像在 XML 文件中定义:

<com.jocajica.shakepic.PuzzleView
    android:id="@+id/imageViewSelected"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:contentDescription="@string/image_selected"
    android:src="@android:drawable/progress_indeterminate_horizontal" />

我需要在图像上绘制一个网格。

【问题讨论】:

  • getTop/getLeft/getBottom/getRight 有什么问题?
  • @blackbelt 我相信这些将返回 ImageView 在其容器内的坐标。 OP想知道ImageView中实际图像的偏移量
  • 没错。我需要知道当前图像的偏移量,getTop/getLeft/getBottom/getRight 只返回 ImageView 在其容器内的坐标。

标签: android android-imageview


【解决方案1】:

根据 Jacob Nordfalk 的链接,我能够生成一个静态方法,允许您从 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;
}

【讨论】:

  • 这将返回负值的偏移量。
  • 不应该是:res[2] = left + actW;res[3] = top + actH;吗?
  • 没有@Zach。 res[2] 和 res[3],如评论文档中所述,是宽度和高度,而不是右下角
  • 感谢 Quentis S. 和 Jacob Nordfalk 提供了非常有用的例程。我冒昧地将返回值从数组更改为 Rect 对象。请参阅下面的答案。
【解决方案2】:

你应该使用 getImageMatrix():

float[] imageMatrix = new float[9];
getImageMatrix().getValues(imageMatrix);
scale = imageMatrix[Matrix.MSCALE_X];
transX = imageMatrix[Matrix.MTRANS_X];

另请参阅
Trying to get the display size of an image in an ImageView

【讨论】:

    【解决方案3】:

    感谢 Quentis S. 和 Jacob Nordfalk 提供了非常有用的例程。

    我冒昧地将返回值从一个数组更改为一个 Rect 对象。

        /**
     * Returns the bitmap position inside an imageView.
     *
     * @param imageView source ImageView
     * @return Rect position of the bitmap in the ImageView
     */
    public static final Rect getBitmapPositionInsideImageView(ImageView imageView)
    {
        Rect rect = new Rect();
    
        if (imageView == null || imageView.getDrawable() == null)
        {
            return rect;
        }
    
        // 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);
    
        // Get image position
        // We assume that the image is centered into ImageView
        int imgViewW = imageView.getWidth();
        int imgViewH = imageView.getHeight();
    
        rect.top  = (int) (imgViewH - actH) / 2;
        rect.left = (int) (imgViewW - actW) / 2;
    
        rect.bottom = rect.top + actH;
        rect.right  = rect.left + actW;
    
        return rect;
    }
    

    【讨论】:

      【解决方案4】:

      重写onLayout方法

          //inside puzzleView
          float[] matrix = new float[9];
          @Override
          protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
      
              super.onLayout(changed, left, top, right, bottom);
              matrix = getMatrix();
      
          }    
          public void getMatrix(){
               return matrix;
          }
      
      
          private float[] getMatrix() {
      
              final float[] matrix = new float[9];
              getImageMatrix().getValues(matrix);
      
              return matrix;
          }
      

      并使用它来获取值

             // Extract the scale and translation values from the matrix.
             float scaleX = matrix[Matrix.MSCALE_X];
             float scaleY = matrix[Matrix.MSCALE_Y];
             float transX = matrix[Matrix.MTRANS_X];
             float transY = matrix[Matrix.MTRANS_Y];
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-14
        • 1970-01-01
        相关资源
        最近更新 更多