How to get zoom value of arbitrary matrix?

2019-04-30 12:07发布

问题:

An image is scaled by a matrix:

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

I hope the zoomed image won't be less than the half of original, so the total zoom should not less that 0.5.

But how to do that? I tried to get the first value of matrix to check:

float pendingZoom = 0.6f;

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

Then:

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

unfortunately, it doesn't work sometimes. If the image has been rotated, the scalex may be negative, the pendingZoom will be negative too.

How to do this correctly?


UPDATE

I just found the values[Matrix.MSCALE_X] is not a realiable zoom value. I use it to calculate the new width of a rect, it's not correct.

Instead, I tried to map two points by the matrix, and calculate the two distances:

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

I can get correct scale value now. But I'm not sure if it's best solution.

回答1:

    float scalex = values[Matrix.MSCALE_X];
    float skewy = values[Matrix.MSKEW_Y];
    float scale = (float) Math.sqrt(scalex * scalex + skewy * skewy);

This solution looks simpler but I think that your's is much more clear and almost as fast as this one.



回答2:

you can just take the absolute value

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