2

I have a custom view that extends SurfaceView. I am drawing an image on the canvas. When the user touches a point on the canvas, i want to show a magnified view of the area around the touched co-ordinates. And preferably, as the finger moves around, i would like to update the magnified view's content accordingly.

I was wondering if the android platform supports such a functionality natively. If not, can one of you point me to a good example that can get me started or share ideas on how to implement it. I don't do much 2D or 3D graphics of this sort and am still trying to understand the Canvas and Matrix Classes to see what i can be use.

I searched the forum for a similar question but could not find any. So, pls don't flag me for asking a question that already exists.

And no - i am not using OpenGL-ES or any such 3rd party library (yet).

Thanks All.

nmw
  • 6,664
  • 3
  • 31
  • 32
VJ Vélan Solutions
  • 6,434
  • 5
  • 49
  • 63

1 Answers1

10

To zoom the image you're drawing on the canvas:

Create a BitmapShader (using the bitmap of the image you're drawing), a Matrix and a Paint:

shader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP);
matrix = new Matrix();
shaderPaint = new Paint();
shaderPaint.setShader(shader);

On a touch event record the touch position (e.g. in a PointF):

zoomPos.x = event.getX();
zoomPos.y = event.getY();

...and set up the shader's matrix (I do this on each touch, there's probably a better way):

matrix.reset();
matrix.postScale(2f, 2f);
matrix.postTranslate(-zoomPos.x, -zoomPos.y);
shader.setLocalMatrix(matrix);

Then in the drawing code, draw a circle using the shader Paint.

canvas.drawCircle(zoomPos.x, zoomPos.y, size_of_the_circle, shaderPaint);

Edit

The two lines:

matrix.postScale(2f, 2f);
matrix.postTranslate(-zoomPos.x, -zoomPos.y);

Can be replaced with one:

matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);

This allows the scale factor to be changed without breaking the offset.

nmw
  • 6,664
  • 3
  • 31
  • 32
  • quick follow up question. In shader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP); can u help me to create bmp? I need a certain area (i know the x, y and width i.e the Rect info) around the point i touch. How do i create pick that area from the underlying background of the screen? Thanks – VJ Vélan Solutions Jul 13 '12 at 18:01
  • 1
    If the "underlying background" is just a static image, then create the shader as described above as soon as you've loaded that image. You don't need to crop out a section to zoom. However, if you're trying to magnify a dynamic or composite image (i.e. you're drawing lots of images on top of each other) then probably best cover that in another post - which I can answer. – nmw Jul 14 '12 at 08:39
  • 1
    thanks @neilmw. In my case, i have an image on the canvas. The user can pinch-zoom and scale that image. And once zoomed, the image can be panned in either horizontal/vertical direction. I was having a challenging time to zoom the relevant part of the image when the image was panned. But i have kinda figured out how to do it now. Thanks again for your help. – VJ Vélan Solutions Jul 15 '12 at 21:33
  • @nmw How should I solve for the case where I'm drawing lots of images on top of each other? – Vinay Gaba Jul 08 '17 at 08:15