问题
I have a matrix for transforming an image. Old matrix is a function of a scale and translation. Now how to apply rotation from center in old Matrix without affecting the other transformation like scale and translation.
i already try this
//get old matrix
Matrix matrix = getImageMatrix();
float tx = getMatrixValue(matrix, Matrix.MTRANS_X);
float ty = getMatrixValue(matrix, Matrix.MTRANS_Y);
float scaleX = getMatrixValue(matrix, Matrix.MSCALE_X);
float scaleY = getMatrixValue(matrix, Matrix.MSCALE_Y);
float skewX = getMatrixValue(matrix, Matrix.MSKEW_X);
float skewY = getMatrixValue(matrix, Matrix.MSKEW_Y);
//calculating the actual scale
float sx = (float)Math.sqrt((scaleX*scaleX)+(skewY*skewY));
float sy = (float)Math.sqrt((scaleY*scaleY)+(skewX*skewX));
//calculating the rotateAngle
float rAngle = Math.round(Math.atan2(scaleX, skewX) * (180 / Math.PI));
//calculate the actual width and height of image
float width = sx * drawable.getIntrinsicWidth();
float height = sy * drawable.getIntrinsicHeight();
//calculate the center pivot for rotation
float cx = (width/2)+tx;
float cy = (height/2)+ty;
//Applying Rotation from center pivot
matrix.postTranslate(-cx , -cy);
matrix.postRotate(rotateAngle, (width/2)+tx, (height/2)+ty);
matrix.postTranslate(cx, cy);
setImageMatrix(matrix);
invalidate();
i didn't get the desire result of rotation. It makes change in translation. what's wrong i did in this..?
Have a look on full code (line no 220 to onwards) http://pastebin.com/NWrNw0Nd
回答1:
This is how you do it. Short and sweet.
private RectF rect = new RectF(); // only allocate once
public void rotate(int rotateAngle) {
if (rotateAngle % 90 != 0) {
throw new IllegalArgumentException("angle must be a multiple of 90 degrees");
}
Matrix matrix = getImageMatrix();
// get the original dimensions of the drawable
rect.set(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
// calculate where the current matrix has put the image
matrix.mapRect(rect); // rect now has updated coordinates
// rotate pivoting on the center point
matrix.postRotate(rotateAngle, rect.centerX(), rect.centerY());
setImageMatrix(matrix); // i think setImageMatrix() will call invalidate() itself
}
回答2:
I'm not 100% certain, but I believe the problem is that you are attempting to extract and then reapply the tx and ty values. Matrices kinda "remember" what has already been done, so this isn't necessary if you are using the postRotate/postTranslate/post* functions. Try something like this instead:
Matrix matrix = getImageMatrix();
float rotateAngle = 90.0; // or whatever
//calculate the actual width and height of image
float width = drawable.getIntrinsicWidth();
float height = drawable.getIntrinsicHeight();
//calculate the center pivot for rotation
float cx = (width/2);
float cy = (height/2);
//Applying Rotation from center pivot
matrix.postTranslate(-cx , -cy);
matrix.postRotate(rotateAngle);
matrix.postTranslate(cx, cy);
setImageMatrix(matrix);
invalidate();
I believe that'll do a 90 degree rotation about the center for you.
来源:https://stackoverflow.com/questions/38811559/apply-rotate-transformation-in-old-matrix-android