Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zooming in android - keep image in view

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();
}
like image 589
Dynde Avatar asked Sep 27 '11 11:09

Dynde


2 Answers

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.

like image 88
Pointer Null Avatar answered Nov 16 '22 05:11

Pointer Null


A simple solution is to use this widget

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

like image 37
ingsaurabh Avatar answered Nov 16 '22 07:11

ingsaurabh