6

I know there are tons of threads on actually getting pinch zoom implemented - but I got this far already.

I'm using SimpleScaleGestureListener to handle the pinching. I've managed to make sure you can't zoom out farther than to keep the image height the same as the screen size (so you're image height will always be at least the height of the available screen size).

However, I'm looking for a way to automatically detect if the image is being panned outside of these boundaries. Just like the standard android way of displaying the image. So if I zoom in, and pan the image up, and then zoom out, I want it to detect when the bottom of the image reaches the bottom of the screen, and then 'pivot' of the zooming adjusts accordingly, thus never allowing "whitespace" above or below the image itself. Can anyone help me?

For reference, here's my onScale and onDraw methods:

public boolean onScale(ScaleGestureDetector detector){
    float minScale = (float) ((float) SCREEN_SIZE.y / (float) DRAWABLE_SIZE.y);
    mScaleFactor *= detector.getScaleFactor();
    mScaleFactor = Math.max(minScale, Math.min(mScaleFactor, 5.0f));
    invalidate();
    return true;
}

protected void onDraw(Canvas canvas) {
    canvas.save();
    canvas.drawColor(Color.DKGRAY);
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor, getDrawable().getIntrinsicWidth() / 2,
    getDrawable().getIntrinsicHeight() / 2);

    this.getDrawable().draw(canvas);
    canvas.restore();
}
Dynde
  • 2,592
  • 4
  • 33
  • 56

2 Answers2

3

You can use android.graphics.Matrix to transform drawn Bitmap. Matrix holds both scale and translation in it.

You would simply apply the matrix to canvas: canvas.setMatrix

You can easily compute fit-to-screen for desired rectangle:

Matrix.setRectToRect

where source is your image's (Bitmap's) real resolution rectangle with 0,0 in left/top and width/heght in right bottom. dst is target view's rectangle where Bitmap will be drawn.

Then you may also solve your task - to know where borders of your image would be drawn. Matrix.mapRect will compute where your Bitmap's rectangle (as discussed previously) will appear on screen in screen's coordinates. Then you may simply where image's left side is drawn relative to screen's left side, same for top/right/bottom.

I'm not going to give you code, just hints which way to go. I've recently coded image viewer with pinch-zoom, fit-to-screen, animated transitions, etc, and all was done using Matrix and manipulations of that.

Pointer Null
  • 39,597
  • 13
  • 90
  • 111
  • Thank you! I'll look into the matrix. I appreciate that you don't want to share code, but do you maybe have a link to good resources on the matrix and how to overcome my specific problem? Maybe a good tutorial? I'll of course google myself, but if you had any 'top-notch' suggestions, I'd be much obliged :) – Dynde Sep 28 '11 at 06:30
  • Don't know about particular link. However, try to look for 2D transformation, matrix math, etc. It's not too difficult, and Matrix is very powerful in graphics. On Android's Canvas it's just 2D Matrix. – Pointer Null Sep 28 '11 at 10:11
  • @mice hi, Can you send me the code of this particular problem with matrix. I want to use zooming and panning in Canvas. But I am not able to do Panning .. I did google but using Matrix I cant find anything. Thanks in advance. – anddev Feb 16 '12 at 09:54
2

A simple solution is to use this widget

http://blog.sephiroth.it/2011/04/04/imageview-zoom-and-scroll/

ingsaurabh
  • 15,249
  • 7
  • 52
  • 81
  • 2
    Simple solutions can be great :) However, I'm mostly interested in learning how to tackle this problem, then simply using other code - although it could prove useful as inspiration :) – Dynde Sep 28 '11 at 06:30
  • The code is extracted from default Gallery app and its a long time when I worked on it the most I remember is it has default matrix for image then on zooming out/in its mapping changed matrix – ingsaurabh Sep 28 '11 at 06:35