Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageView Pinch-zoom Scale Limits and pan bounds

Tags:

android

I wanted to create a gallery with images. The images within the gallery should be zoomable and pannable. I could able to pinch-zoom an image but could not able to set zoom limits and prevent the image from being panned off the screen. I used the following code to zoom an image:

First approach : I used TouchImageView to supply images to the gallery, this allows me to pinch-zoom but I can't scroll the gallery, i.e. I can't differentiate between 'single tab event' and 'tab to scroll event'.

Second approach : Used ImageView to supply images to gallery, and if user clicks on any of the gallery items display the selected image in TouchImageView, where the user can Pinch-Zoom an image. But this also prevents me from scrolling the gallery view. And also how to set zoom limits and pan bounds on the selected image?

like image 671
Audum Avatar asked Oct 07 '10 11:10

Audum


People also ask

How to zoom and Pan an image inside it?

An Image View with touch can be used to make a great tool that provides zooming and panning an image inside it. So that the user can view very large images inside a small screen. In Android, we all have seen the built-in Gallery.

What is the default value for the zoom?

Default value: 1. * @param min min zoom multiplier. * Reset zoom and translation to initial state. * Set zoom to the specified scale. Image will be centered by default.

How do i Zoom in on an image on Android?

You will be building an app that have an Android ImageView and a TextView, when you tap on the ImageView an Android Alertdialog will appear on the screen showing you the image in full size where you can pinch and zoom on the image itself.

What is ontouchimageviewlistener set in Android?

// OnTouchImageViewListener is set: TouchImageView pinch zoomed by user. * an animated zoom in/out graphic to the image. // with every frame. * of the zoom.


3 Answers

This fixed the zoom-limit problem for me. After the image is zoomed in/out to the limit, it just stops going further. It's also smooth and there are no lags. 0.7 and 2.0 are the minimum and maximum zoom levels.

....
} else if (mode == ZOOM) {
    float[] f = new float[9];

    float newDist = spacing(event);
    if (newDist > 10f) {
            matrix.set(savedMatrix);
            float tScale = newDist / dist;
            matrix.postScale(tScale, tScale, mid.x, mid.y);
    }

    matrix.getValues(f);
    float scaleX = f[Matrix.MSCALE_X];
    float scaleY = f[Matrix.MSCALE_Y];

    if(scaleX <= 0.7f) {
            matrix.postScale((0.7f)/scaleX, (0.7f)/scaleY, mid.x, mid.y);
    } else if(scaleX >= 2.5f) {
            matrix.postScale((2.5f)/scaleX, (2.5f)/scaleY, mid.x, mid.y);
    }
}
....        
like image 70
Arjun Avatar answered Nov 15 '22 14:11

Arjun


You can set zoom limit by adding these lines to ACTION_MOVE, mode == ZOOM:

float[] f = new float[9];
matrix.getValues(f);

float scaleX = f[Matrix.MSCALE_X];
float scaleY = f[Matrix.MSCALE_Y];
if (scaleX > MAX_SCALE || scaleY > MAX_SCALE) return true;

Similarly, add lines to ACTION_MOVE, mode == DRAG that takes into account the original location of your image, the translated length, and then compare them to the bounds.

like image 42
Li_W Avatar answered Nov 15 '22 12:11

Li_W


Have tried using this code below and although it works I found that it was causing small incremental values to accumulate in Trans X and Trans Y leading to the picture slowly moving off screen.

if(scaleX <= 0.7f)
            matrix.postScale((0.7f)/scaleX, (0.7f)/scaleY, mid.x, mid.y);
    else if(scaleX >= 2.5f) 
            matrix.postScale((2.5f)/scaleX, (2.5f)/scaleY, mid.x, mid.y);

I fixed this be storing an original matrix in a float[] (1,0,0,0,1,0,0,0,1) and resetting the matrix back to these values whenever scaleX < 1. Hope this helps someone else one day :)

if(scaleX <= 1.0f) {                                   
    float[] originalmatrixvalues = new float[] {1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
    matrix.setValues(originalmatrixvalues); 
} else if(scaleX >= 2.5f) {
    matrix.postScale((2.5f)/scaleX, (2.5f)/scaleY, mid.x, mid.y);
}
like image 42
Sico Syco Avatar answered Nov 15 '22 13:11

Sico Syco