Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to center imageView with matrix scaletype?

I'm using Android Studio to display an imageView. I'm using pinch zoom to interact with my ImageView.

Code:

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener{
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scale = scale * detector.getScaleFactor();
        scale = Math.max(0.1f, Math.min(scale, 5f));
        matrix.setScale(scale, scale);

        imageView.setImageMatrix(matrix);
        return true;
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    scaleGestureDetector.onTouchEvent(event);
    return true;
}

Zoom is fine, but problem is the position of imageview, it's stuck in left upper corner. Tried layout changes but nothing to do. After some reseaches, I've seen these links in the forum ImageView Center in position with ScaleType Matrix and Center the image in ImageView after zoom-pinch, but these solutions aren't working, I've also checked the links given inside.

Help would be appreciated,

Thanks !

EDIT: Added the piece of code on how I get my ImageView

Picasso.with(this).load(url).resize(350, 330).centerInside().into(imageView);

onCreate Code

onCreate

ScaleListner Class and Gesture Code

listener

like image 324
Jay Avatar asked May 17 '16 07:05

Jay


People also ask

What is the use of center_crop scaletype in imageview?

The CENTER_CROP ScaleType is used to place the image in the center of the ImageView and scale the image uniformly by maintaining the aspect ratio. So basically it scales in such a way that one of the width or height of the image becomes equal to the width and height of the ImageView.

How to scale image in imageview?

Scale using the image matrix when drawing. While not technically an ImageView.ScaleType this will come in handy. If you notice with CENTER_INSIDE, FIT_CENTER, FIT_END and FIT_START the actual bounds of the ImageView are much larger than the scaled image.

What is the use of matrix scaletype?

The MATRIX ScaleType is used to scale the image according to some user-defined MATRIX. Basically, we use a Matrix to manipulate the canvas while drawing some graphics. So, when using a Matrix with an ImageView, you can use it to flip, rotate, translate, etc with your image.

What is the use of the center scaletype?

The CENTER ScaleType is used to place the image to the center of the ImageView in which that image is present by keeping the same aspect ratio. No scaling is done here and while centering the image, if the image is so big such that it is not fitting in the center, then some parts of the image will be cropped.


1 Answers

    Picasso.with(this).load(url).into(imageView, new Callback.EmptyCallback() {
        @Override
        public void onSuccess() {
            Drawable d = imageView.getDrawable();
            // TODO: check that d isn't null

            RectF imageRectF = new RectF(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
            RectF viewRectF = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());
            matrix.setRectToRect(imageRectF, viewRectF, ScaleToFit.CENTER);
            imageView.setImageMatrix(matrix);
        }
    });

Edit 2:

How to center the image like CENTER_INSIDE but using matrix:

First we need a rectangle with the image dimensions:

    Drawable d = imageView.getDrawable();
    // TODO: check that d isn't null

    RectF imageRectF = new RectF(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());

Next you need a rectangle with the view dimensions:

    RectF viewRectF = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());

Now we run a method on matrix that will center the image in the view:

    matrix.setRectToRect(imageRectF, viewRectF, ScaleToFit.CENTER);

What this does is set up the matrix so that the first rectangle will transform to the second rectangle. ScaleToFit.CENTER will preserve the aspect ratio and have the same effect as scale type CENTER_INSIDE.

So if you call

    imageView.setImageMatrix(matrix);

at this point, you will have a centered image.


Edit: I think you are almost there.

Your matrix will undo the image centering that Picasso did, so you need to put in a translation to center the image before you scale it.

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        Drawable d = imageView.getDrawable();
        // if d is null, then Picasso hasn't loaded the image yet

        float offsetX = (imageView.getWidth() - d.getIntrinsicWidth()) / 2F;
        float offsetY = (imageView.getHeight() - d.getIntrinsicHeight()) / 2F;

        float centerX = imageView.getWidth() / 2F;
        float centerY = imageView.getHeight() / 2F;

        // note that these offset and center values don't change with the scaling, 
        // so you can calculate them somewhere else and then use them here.

        scale *= detector.getScaleFactor();
        scale = Math.max(0.1f, Math.min(scale, 5f));

        matrix.setScale(scale, scale, centerX, centerY);
        matrix.preTranslate(offsetX, offsetY);

        imageView.setImageMatrix(matrix);
    }

You are using setScale(float sx, float sy). There is another version, setScale(float sx, float sy, float px, float py) where px,py is a pivot point.

So if you want to center your image, determine the center of your view and use the x,y value as the pivot point.

You will also want to center the image inside the view, so you will need to move the image first before you scale.

    float offsetX = (imageView.getWidth() - bitmap.getIntrinsicWidth()) / 2F;
    float offsetY = (imageView.getHeight() - bitmap.getIntrinsicHeight()) / 2F;

    float centerX = imageView.getWidth() / 2F;
    float centerY = imageView.getHeight() / 2F;

    matrix.setScale(scale, scale, centerX, centerY);
    matrix.preTranslate(offsetX, offsetY);
like image 156
kris larson Avatar answered Oct 12 '22 22:10

kris larson