【问题标题】:How to get zoom value of arbitrary matrix?如何获得任意矩阵的缩放值?
【发布时间】:2012-08-28 22:08:54
【问题描述】:

图像按矩阵缩放:

Matrix matrix = new Matrix();
matrix.postScale(...);
matrix.postTranslate(...);
matrix.postRotate(...);
...

希望放大后的图片不会小于原图的一半,所以总的缩放不应该小于0.5。

但是怎么做呢?我试图获取要检查的矩阵的第一个值:

float pendingZoom = 0.6f;

float[] values = new float[9];
Matrix.getValues(values);
float scalex = values[Matrix.MSCALE_X];

然后:

if(scalex<0.5) {
    pendingZoom = pendingZoom * (0.5f / scalex);
}

不幸的是,它有时不起作用。如果图像已经旋转,scalex 可能是负数,pendingZoom 也可能是负数。

如何正确地做到这一点?


更新

我刚刚发现values[Matrix.MSCALE_X] 不是一个可实现的缩放值。我用它来计算矩形的新宽度,这是不正确的。

相反,我尝试通过矩阵映射两个点,并计算两个距离:

PointF newP1 = mapPoint(matrix, new PointF(0, 0));
PointF newP2 = mapPoint(matrix, new PointF(width, 0));
float scale = calcDistance(newP1, newP2) / width;

我现在可以得到正确的scale 值。但我不确定这是否是最佳解决方案。

【问题讨论】:

  • 有谁知道为什么旋转后的矩阵不同?似乎 postRotate 之后“缩放 x”不在 Matrix.MSCALE_X 索引(即 0)下,而是在 1 索引下。
  • 将矩阵分解为平移、缩放和旋转解释here

标签: android matrix rotation zooming scale


【解决方案1】:
    float scalex = values[Matrix.MSCALE_X];
    float skewy = values[Matrix.MSKEW_Y];
    float scale = (float) Math.sqrt(scalex * scalex + skewy * skewy);

这个解决方案看起来更简单,但我认为你的解决方案更清晰,几乎和这个解决方案一样快。

【讨论】:

  • @Freewind 我认为您的解决方案很棒。很清楚它是如何工作的,并且这个问题的任何解决方案都需要平方根提取,因此它不能更快​​地完成。我唯一的建议是不要在负责滚动的代码中执行 new PointF() ,因为它会触发垃圾收集器并且不利于滚动性能。请改用一些预先创建的 PointF 成员变量。
  • 更新我的答案只是为了提供另一种解决方案
  • @nickes 这个答案拯救了我的一天!但是你能解释一下吗?我的意思是,为什么 Math.sqrt(scalex * scalex + skewy * skewy) 是答案,而不是 values[Matrix.MSCALE_X] 或 values[Matrix.MSCALE_Y]?
  • 我需要解释那个公式
【解决方案2】:

你可以取绝对值

Math.abs(mMatrixValues[Matrix.MSCALE_X]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    相关资源
    最近更新 更多