Reputation: 11
I am loading an imageview with a jpg from the SD card, and scaling it so that it is maximally enlarged without clipping. I then want to overlay the bitmap with a circle, centered on the coordinates of a touch event.
I save the current bitmap from the imageview, create a new overlay bitmap, add a canvas, draw the original bitmap, draw the circle, reapply scaling code to the new overlay bitmap, then reload the imageview with the new overlay bitmap. The first time I touch the image to draw the circle, the circle is accurately drawn, but the image scaling is not correct. On the second touch, the image scaling is corrected, but the circle is drawn in the "wrong" place- it is drawn where I touched on the screen, but now the image is scaled correctly, so the target has moved. On the third and all subsequent touches, things work as I'd hoped they would from the start.
Here is my code:
private static Matrix curMatrix = new Matrix();
public boolean onTouch(View v, MotionEvent event) {
int eventType = event.getAction() & MotionEvent.ACTION_MASK;
switch (eventType) {
case MotionEvent.ACTION_UP:
ImageView i = (ImageView) v;
//Save the current bitmap
i.buildDrawingCache();
Bitmap bm = i.getDrawingCache();
//Create new overlay bitmap
Bitmap bmOverlay = Bitmap.createBitmap(i.getWidth(), i.getHeight(), Bitmap.Config.ARGB_8888);
//Create new drawing canvas and paint
Canvas c = new Canvas(bmOverlay);
Paint p = new Paint();
p.setColor(Color.RED);
p.setAlpha(50);
//Draw the saved bitmap onto the canvas
c.drawBitmap(bm, new Matrix(), null);
//Draw a circle on the current canvas, centered on event coordinates
c.drawCircle(event.getX(), event.getY(), 100F, p);
//Autosize canvas to previous imageview settings
RectF drawableRect = new RectF(0, 0, (float) c.getWidth(), (float) c.getHeight());
RectF viewRect = new RectF(0, 0, (float) i.getWidth(), (float) i.getHeight());
curMatrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
//Apply the autosize transformation
i.setImageMatrix(curMatrix);
//Reload the imageview with the new bitmap
i.setImageBitmap(bmOverlay);
}
return true;
}
And here are some images to better explain what is happening:
Start - I want to click on the fish:
First click - click is accurate, scaling is lost:
Second click - scaling reappears, click applied to original scaling though, so it is off:
Third and all subsequent clicks - works as I'd hoped it would from the start:
Thanks for any help!
Upvotes: 0
Views: 1059
Reputation: 11
As usual, I was over complicating things. For those interested, the following simpler code works. Simply set this as a TouchListener for an ImageView, and when you touch the image, it will draw a 100(pixel?) radius semi-transparent red circle centered on your touch point:
public class GetCoordinatesTouchListener implements OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
int eventType = event.getAction() & MotionEvent.ACTION_MASK;
switch (eventType) {
case MotionEvent.ACTION_UP:
ImageView i = (ImageView) v;
//Save the current bitmap from the imageview
i.buildDrawingCache();
Bitmap bm = i.getDrawingCache();
//Create new overlay bitmap
Bitmap bmOverlay = Bitmap.createBitmap(i.getWidth(), i.getHeight(), Bitmap.Config.ARGB_8888);
//Create new drawing canvas and paint
Canvas c = new Canvas(bmOverlay);
Paint p = new Paint();
p.setColor(Color.RED);
p.setAlpha(50);
//Draw the saved bitmap onto the canvas
c.drawBitmap(bm, new Matrix(), null);
//Draw a circle on the current canvas, centered on event coordinates
c.drawCircle(event.getX(), event.getY(), 100F, p);
//Reload the imageview with the new bitmap with FIT_XY scaling
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setImageBitmap(bmOverlay);
}
return true;
}
}
Upvotes: 1