Android Imageview Scaling and Translating Issue

Android image view matrix scale + translate

There's a convenient method called Matrix.setRectToRect(RectF, RectF, ScaleToFit) to help you here.

Matrix m = imageView.getImageMatrix();
RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
RectF viewRect = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());
m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
imageView.setImageMatrix(m);

That should set the matrix m to have combo of scaling and translate values that is needed to show the drawable centered and fit within the ImageView widget.

Simultaneously scale and translate ImageView based on Target

I was able to achieve this animation by wrapping the target View in a layout group and animating them separately.

In other words, I translate the wrapper layout, and scale the child view. Translating and scaling the same view at the same time always seems to result in unexpected animation trajectories as the scaling messes with the coordinate system the translate animation is using.

translateTarget.animate().x(deltaX).y(deltaY).setDuration(1000);
scaleTarget.animate().scaleX(0.01f).scaleY(0.01f).setDuration(1000)

How to center imageView with matrix scaletype?

    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);


Related Topics



Leave a reply



Submit