如何使用矩阵缩放类型居中imageView?

6

我正在使用 Android Studio 显示一个 imageView。我正在使用捏合缩放交互我的 ImageView。

代码:

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很好,但问题是ImageView的位置被固定在左上角。尝试了布局更改,但无济于事。经过一些研究,在论坛中看到了这些链接:ImageView Center in position with ScaleType MatrixCenter the image in ImageView after zoom-pinch,但这些解决方案都不起作用,我也检查了给出的链接。
感谢您的帮助!
编辑:添加了获取ImageView的代码片段。
Picasso.with(this).load(url).resize(350, 330).centerInside().into(imageView);

onCreate 代码

onCreate

ScaleListener 类和手势代码

listener


我已经尝试过这个方法,但并没有帮助到我。@pskink - Jay
使用Log.d方法,在您每次更改矩阵时随时转储它。 - pskink
请问您有示例吗?@pskink - Jay
例子?什么的例子? - pskink
@pskink 是的,这一行代码:imageView.setImageMatrix(matrix); - Jay
显示剩余4条评论
1个回答

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

编辑2:

如何使用矩阵将图像居中显示,类似于CENTER_INSIDE的效果:

首先,我们需要一个与图像尺寸相同的矩形:

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

这段代码的作用是设置矩阵,使第一个矩形变换为第二个矩形。使用 ScaleToFit.CENTER 可以保持纵横比,并具有与缩放类型 CENTER_INSIDE 相同的效果。
因此,如果您调用
    imageView.setImageMatrix(matrix);

此时,您将拥有一张居中的图片。


编辑:我认为您已经接近成功了。

您的矩阵将撤销Picasso所做的图像居中处理,因此您需要添加一个平移操作来使图像居中,然后再进行缩放。

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

您正在使用 setScale(float sx, float sy)。还有另一个版本的方法,setScale(float sx, float sy, float px, float py),其中px、py是枢轴点

如果您想将图像居中,确定视图的中心并使用x、y值作为枢轴点。

您还需要在缩放之前先将图像居中于视图中心。

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

在变量视图、图片(我尝试替换的那个)和 matrix.preTransform 上遇到了一些错误。 - Jay
1
应该是 preTranslate,我更新了我的答案。你可以不使用 preTranslate 方法来查看图像缩放而不被卡在左上角。但我打赌你的图像没有居中,所以你需要在其中加入一些平移来将图像居中显示。 - kris larson
我更新了我的代码,实际上,我正在使用从其他活动传递的URL来填充我的ImageView的Picasso,感谢您的帮助!我没有直接使用位图,我该怎么做? - Jay
1
好的,我觉得我知道发生了什么事情。所以Picasso是在将图像居中,但是一旦你把矩阵应用到ImageView上,它又回到了左上角? - kris larson
所以一旦你开始缩放,一切都没问题,但是图像的起始位置不正确? - kris larson
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接