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
ScaleListner Class and Gesture Code
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.
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.
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.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With