Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get zoom value of arbitrary matrix?

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.

like image 455
Freewind Avatar asked Sep 04 '12 09:09

Freewind


1 Answers

    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.

like image 177
Dmitry Ryadnenko Avatar answered Oct 14 '22 08:10

Dmitry Ryadnenko