Вращение изображения с использованием AffineTransformOp
(на мой взгляд) немного нелогично ... Само вращение легко, но, как вы, наверное, уже поняли, трудная часть корректно переводится, так что верхнийлевая часть изображения (или ограничивающая рамка, в случае поворота без квадранта) после поворота точно попадает в начало координат.
Если вам нужно повернуть на произвольный угол, выможно использовать следующий, довольно общий код:
public static BufferedImage rotate(BufferedImage src, double degrees) {
double angle = toRadians(degrees); // Allows any angle
double sin = abs(sin(angle));
double cos = abs(cos(angle));
int width = src.getWidth();
int height = src.getHeight();
// Compute new width and height
double newWidth = width * cos + height * sin;
double newHeight = height * cos + width * sin;
// Build transform
AffineTransform transform = new AffineTransform();
transform.translate(newWidth / 2.0, newHeight / 2.0);
transform.rotate(angle);
transform.translate(-width / 2.0, -height / 2.0);
BufferedImageOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
return operation.filter(src, null);
}
Однако, если вы хотите повернуть кратные только на 90 градусов, вы можете использовать этот немного более быстрый вариант:
public static BufferedImage rotate90(BufferedImage src, int quadrants) {
// Allows any multiple of 90 degree rotations (1, 2, 3)
int width = src.getWidth();
int height = src.getHeight();
// Compute new width and height
boolean swapXY = quadrants % 2 != 0;
int newWidth = swapXY ? height : width;
int newHeight = swapXY ? width : height;
// Build transform
AffineTransform transform = new AffineTransform();
transform.translate(newWidth / 2.0, newHeight / 2.0);
transform.quadrantRotate(quadrants);
transform.translate(-width / 2.0, -height / 2.0);
BufferedImageOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); // 1:1 mapping
return operation.filter(src, null);
}