正确的图像缩放转换

时间:2010-01-29 16:09:07

标签: android matrix imageview

我正在为Android编写一个应用程序(虽然我认为这是一个通用的问题),我需要显示一个可以滚动和缩放的大图像(在ImageView中)。我已经设法通过捕获触摸事件和执行矩阵翻译来滚动工作,我现在正在进行缩放。

如果我只是对图像应用比例变换,它会在原点放大,这是屏幕的左上角。我想放大屏幕的中心。 从我所读到的,这意味着我需要一个转换,使原点成为屏幕的中心。我认为所需要的是以下内容 - 假设屏幕中心为(5,5)以简化......

-Translate by (-5, -5)
-Scale by the zoom factor
-Translate by (+5, +5)*zoomfactor

不幸的是,这看起来似乎不起作用 - 变焦似乎在任何地方但中心......有人可以帮助我吗?

编辑:这是现在可以使用的代码

    Matrix zoommatrix = new Matrix();
    float[] centerpoint = {targetimageview.getWidth()/2.0f, targetimageview.getHeight()/2.0f};

    zoommatrix.postScale(zoomfactor, zoomfactor, centerpoint[0], centerpoint[1]);
    zoommatrix.preConcat(targetimageview.getImageMatrix());

    targetimageview.setImageMatrix(zoommatrix);
    targetimageview.invalidate();

1 个答案:

答案 0 :(得分:3)

在Android源代码的相机应用中检查ImageViewTouchBase;它的“zoomTo”方法可以做到这一点:

protected void zoomTo(float scale, float centerX, float centerY) {
    if (scale > mMaxZoom) {
        scale = mMaxZoom;
    }

    float oldScale = getScale();
    float deltaScale = scale / oldScale;

    mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY);
    setImageMatrix(getImageViewMatrix());
    center(true, true);
}

那个中心方法可能就是你真正关心的一点:

    protected void center(boolean horizontal, boolean vertical) {
    if (mBitmapDisplayed.getBitmap() == null) {
        return;
    }

    Matrix m = getImageViewMatrix();

    RectF rect = new RectF(0, 0,
            mBitmapDisplayed.getBitmap().getWidth(),
            mBitmapDisplayed.getBitmap().getHeight());

    m.mapRect(rect);

    float height = rect.height();
    float width  = rect.width();

    float deltaX = 0, deltaY = 0;

    if (vertical) {
        int viewHeight = getHeight();
        if (height < viewHeight) {
            deltaY = (viewHeight - height) / 2 - rect.top;
        } else if (rect.top > 0) {
            deltaY = -rect.top;
        } else if (rect.bottom < viewHeight) {
            deltaY = getHeight() - rect.bottom;
        }
    }

    if (horizontal) {
        int viewWidth = getWidth();
        if (width < viewWidth) {
            deltaX = (viewWidth - width) / 2 - rect.left;
        } else if (rect.left > 0) {
            deltaX = -rect.left;
        } else if (rect.right < viewWidth) {
            deltaX = viewWidth - rect.right;
        }
    }

    postTranslate(deltaX, deltaY);
    setImageMatrix(getImageViewMatrix());
}