I am trying to allow the user to touch the image and then basically a cirular magnifier will show that will allow the user to better select a certain area on the image. When the user releases the touch the magnified portion will dissapear. This is used on several photo editing apps and I am trying to implement my own version of it. The code I have below does magnify a circular portion of the imageview but does not delete or clear the zoom once I release my finger. I currently set a bitmap to a canvas using canvas = new Canvas(bitMap);
and then set the imageview using takenPhoto.setImageBitmap(bitMap);
I am not sure if I am going about it the right way. The onTouch code is below:
zoomPos = new PointF(0,0); takenPhoto.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: zoomPos.x = event.getX(); zoomPos.y = event.getY(); matrix.reset(); matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); shader.setLocalMatrix(matrix); canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint); takenPhoto.invalidate(); break; case MotionEvent.ACTION_MOVE: zoomPos.x = event.getX(); zoomPos.y = event.getY(); matrix.reset(); matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint); takenPhoto.invalidate(); break; case MotionEvent.ACTION_UP: //clear zoom here? break; case MotionEvent.ACTION_CANCEL: break; default: break; } return true; } });
Adapting your code, I was able to get the following approach working.
In the onTouch function, set a global point for determining where the user has touched, and set a boolean to indicate whether zooming is currently active or not:
@Override public boolean onTouch(View view, MotionEvent event) { int action = event.getAction(); zoomPos.x = event.getX(); zoomPos.y = event.getY(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: zooming = true; this.invalidate(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: zooming = false; this.invalidate(); break; default: break; } return true; }
Then, in the onDraw method, you use your code for drawing the zoomed in portion:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (zooming) { matrix.reset(); matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); mPaint.getShader().setLocalMatrix(matrix); canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint); } }
Note that for the shader, I used a bitmap shader as described here, which was created with:
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); mShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP); mPaint = new Paint(); mPaint.setShader(mShader);
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