How to get the position of a picture inside an ImageView?

android, android-imageview

Solution

According to Jacob Nordfalk's link, I was able to produce a static method allowing you to get the image position and dimensions from an 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;
}

Problem

I have a gallery of images with different sizes. Each image is displayed inside an `ImageView` sequentially (through `OnTouchListener`). I need to know the position of the frame of the picture I'm showing relatives to the `ImageView` but with the testing I've done I've only gotten the coordinates of `ImageView`. Any idea? I need the values of (x1, y1) and (x2, y2). Thanks in advance. This is my class: ``` 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; } } ``` For now, the source image is defined in XML file: ``` <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" /> ``` I need to draw a grid over the image.

Original source