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.
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;
}
Thank you Quentis S. and Jacob Nordfalk for the very usefull routine.
I took the liberty of changing the return value from an array to a Rect object.
/**
* 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;
}
You should use getImageMatrix():
float[] imageMatrix = new float[9];
getImageMatrix().getValues(imageMatrix);
scale = imageMatrix[Matrix.MSCALE_X];
transX = imageMatrix[Matrix.MTRANS_X];
See also
Trying to get the display size of an image in an ImageView
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With