Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - How to circular zoom/magnify part of image?

Tags:

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;              }              }); 
like image 758
IZI_Shadow_IZI Avatar asked Dec 13 '12 16:12

IZI_Shadow_IZI


1 Answers

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); 
like image 73
qzikl Avatar answered Sep 17 '22 08:09

qzikl