Java Graphics2D 获取旋转图像边界和新坐标
Java Graphics2D obtain rotated image bounding and new coordiinates
我在 Graphics2D 中有一张图像需要旋转,然后获取图像角的新坐标 和 新边界框的尺寸。
我最初尝试使用图像本身,但我认为使用矩形(或多边形)会更容易,从而为我提供更大的灵活性。我最初只是用 AffineTransform.rotate()
对图像进行旋转。但是,如果有一种方法可以单独平移每个角点,那会更干净,这会给我 A1、B1、C1 和 D1 的值。 Graphics2D 中有没有办法 旋转 各个角?
我发现了几个与旋转矩形的边界框尺寸有关的问题,但我似乎无法让它们在 Java 中与 Graphics2D 一起工作。
您只需自己旋转图片的角即可。包 java.awt.geom
提供了 类 Point2D
和 AffineTransform
通过对单个点应用旋转变换来做到这一点。旋转边界框的宽度和高度可以计算为最大和最大旋转 x 和 y 坐标之间的差值,最小 x 和 y 坐标作为偏移量。
以下程序实现了该算法并显示了从 0° 到 360° 的多次旋转的结果,步长为 30°:
package Whosebug;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Demonstration of an implementation to rotate rectangles.
* @author Franz D.
*/
public class ImageRotate
{
/**
* Rotates a rectangle with offset (0,0).
* @param originalWidth original rectangle width
* @param originalHeight original rectangle height
* @param angleRadians rotation angle in radians
* @param rotatedCorners output buffer for the four rotated corners
* @return the bounding box of the rotated rectangle
* @throws NullPointerException if {@code rotatedCorners == null}.
* @throws ArrayIndexOutOfBoundsException if {@code rotatedCorners.length < 4}.
*/
public static Rectangle2D rotateRectangle(int originalWidth, int originalHeight,
double angleRadians,
Point2D[] rotatedCorners) {
// create original corner points
Point2D a0 = new Point2D.Double(0, 0);
Point2D b0 = new Point2D.Double(originalWidth, 0);
Point2D c0 = new Point2D.Double(0, originalHeight);
Point2D d0 = new Point2D.Double(originalWidth, originalHeight);
Point2D[] originalCorners = { a0, b0, c0, d0 };
// create affine rotation transform
AffineTransform transform = AffineTransform.getRotateInstance(angleRadians);
// transform original corners to rotated corners
transform.transform(originalCorners, 0, rotatedCorners, 0, originalCorners.length);
// determine rotated width and height as difference between maximum and
// minimum rotated coordinates
double minRotatedX = Double.POSITIVE_INFINITY;
double maxRotatedX = Double.NEGATIVE_INFINITY;
double minRotatedY = Double.POSITIVE_INFINITY;
double maxRotatedY = Double.NEGATIVE_INFINITY;
for (Point2D rotatedCorner: rotatedCorners) {
minRotatedX = Math.min(minRotatedX, rotatedCorner.getX());
maxRotatedX = Math.max(maxRotatedX, rotatedCorner.getX());
minRotatedY = Math.min(minRotatedY, rotatedCorner.getY());
maxRotatedY = Math.max(maxRotatedY, rotatedCorner.getY());
}
// the bounding box is the rectangle with minimum rotated X and Y as offset
double rotatedWidth = maxRotatedX - minRotatedX;
double rotatedHeight = maxRotatedY - minRotatedY;
Rectangle2D rotatedBounds = new Rectangle2D.Double(
minRotatedX, minRotatedY,
rotatedWidth, rotatedHeight);
return rotatedBounds;
}
/**
* Simple test for {@link #rotateRectangle(int, int, double, java.awt.geom.Point2D[])}.
* @param args ignored
*/
public static void main(String[] args) {
// setup original width
int originalWidth = 500;
int originalHeight = 400;
// create buffer for rotated corners
Point2D[] rotatedCorners = new Point2D[4];
// rotate rectangle from 0° to 360° in 30° steps
for (int angleDegrees = 0; angleDegrees < 360; angleDegrees += 30) {
// convert angle to radians
double angleRadians = Math.toRadians(angleDegrees);
// rotate rectangle
Rectangle2D rotatedBounds = rotateRectangle(
originalWidth, originalHeight,
angleRadians,
rotatedCorners);
// dump results
System.out.println("--- Rotate " + originalWidth + "x" + originalHeight + " by " + angleDegrees + "° ---");
System.out.println("Bounds: " + rotatedBounds);
for (Point2D rotatedCorner: rotatedCorners) {
System.out.println("Corner " + rotatedCorner);
}
}
}
}
如果您的图片没有放置在偏移量 (0, 0) 处,您可以简单地修改方法以将偏移量作为输入参数,并将偏移量坐标添加到原始点。
此外,此方法还围绕原点 (0, 0) 旋转图像(或矩形)。如果您想要其他旋转中心,AffineTransform
提供了 getRotateInstace() 的重载变体,它允许您指定旋转中心(在 API 文档中称为 "anchor")。
我在 Graphics2D 中有一张图像需要旋转,然后获取图像角的新坐标 和 新边界框的尺寸。
我最初尝试使用图像本身,但我认为使用矩形(或多边形)会更容易,从而为我提供更大的灵活性。我最初只是用 AffineTransform.rotate()
对图像进行旋转。但是,如果有一种方法可以单独平移每个角点,那会更干净,这会给我 A1、B1、C1 和 D1 的值。 Graphics2D 中有没有办法 旋转 各个角?
我发现了几个与旋转矩形的边界框尺寸有关的问题,但我似乎无法让它们在 Java 中与 Graphics2D 一起工作。
您只需自己旋转图片的角即可。包 java.awt.geom
提供了 类 Point2D
和 AffineTransform
通过对单个点应用旋转变换来做到这一点。旋转边界框的宽度和高度可以计算为最大和最大旋转 x 和 y 坐标之间的差值,最小 x 和 y 坐标作为偏移量。
以下程序实现了该算法并显示了从 0° 到 360° 的多次旋转的结果,步长为 30°:
package Whosebug;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Demonstration of an implementation to rotate rectangles.
* @author Franz D.
*/
public class ImageRotate
{
/**
* Rotates a rectangle with offset (0,0).
* @param originalWidth original rectangle width
* @param originalHeight original rectangle height
* @param angleRadians rotation angle in radians
* @param rotatedCorners output buffer for the four rotated corners
* @return the bounding box of the rotated rectangle
* @throws NullPointerException if {@code rotatedCorners == null}.
* @throws ArrayIndexOutOfBoundsException if {@code rotatedCorners.length < 4}.
*/
public static Rectangle2D rotateRectangle(int originalWidth, int originalHeight,
double angleRadians,
Point2D[] rotatedCorners) {
// create original corner points
Point2D a0 = new Point2D.Double(0, 0);
Point2D b0 = new Point2D.Double(originalWidth, 0);
Point2D c0 = new Point2D.Double(0, originalHeight);
Point2D d0 = new Point2D.Double(originalWidth, originalHeight);
Point2D[] originalCorners = { a0, b0, c0, d0 };
// create affine rotation transform
AffineTransform transform = AffineTransform.getRotateInstance(angleRadians);
// transform original corners to rotated corners
transform.transform(originalCorners, 0, rotatedCorners, 0, originalCorners.length);
// determine rotated width and height as difference between maximum and
// minimum rotated coordinates
double minRotatedX = Double.POSITIVE_INFINITY;
double maxRotatedX = Double.NEGATIVE_INFINITY;
double minRotatedY = Double.POSITIVE_INFINITY;
double maxRotatedY = Double.NEGATIVE_INFINITY;
for (Point2D rotatedCorner: rotatedCorners) {
minRotatedX = Math.min(minRotatedX, rotatedCorner.getX());
maxRotatedX = Math.max(maxRotatedX, rotatedCorner.getX());
minRotatedY = Math.min(minRotatedY, rotatedCorner.getY());
maxRotatedY = Math.max(maxRotatedY, rotatedCorner.getY());
}
// the bounding box is the rectangle with minimum rotated X and Y as offset
double rotatedWidth = maxRotatedX - minRotatedX;
double rotatedHeight = maxRotatedY - minRotatedY;
Rectangle2D rotatedBounds = new Rectangle2D.Double(
minRotatedX, minRotatedY,
rotatedWidth, rotatedHeight);
return rotatedBounds;
}
/**
* Simple test for {@link #rotateRectangle(int, int, double, java.awt.geom.Point2D[])}.
* @param args ignored
*/
public static void main(String[] args) {
// setup original width
int originalWidth = 500;
int originalHeight = 400;
// create buffer for rotated corners
Point2D[] rotatedCorners = new Point2D[4];
// rotate rectangle from 0° to 360° in 30° steps
for (int angleDegrees = 0; angleDegrees < 360; angleDegrees += 30) {
// convert angle to radians
double angleRadians = Math.toRadians(angleDegrees);
// rotate rectangle
Rectangle2D rotatedBounds = rotateRectangle(
originalWidth, originalHeight,
angleRadians,
rotatedCorners);
// dump results
System.out.println("--- Rotate " + originalWidth + "x" + originalHeight + " by " + angleDegrees + "° ---");
System.out.println("Bounds: " + rotatedBounds);
for (Point2D rotatedCorner: rotatedCorners) {
System.out.println("Corner " + rotatedCorner);
}
}
}
}
如果您的图片没有放置在偏移量 (0, 0) 处,您可以简单地修改方法以将偏移量作为输入参数,并将偏移量坐标添加到原始点。
此外,此方法还围绕原点 (0, 0) 旋转图像(或矩形)。如果您想要其他旋转中心,AffineTransform
提供了 getRotateInstace() 的重载变体,它允许您指定旋转中心(在 API 文档中称为 "anchor")。