Java,使用仿射变换不完全居中旋转

Java,使用仿射变换不完全居中旋转,java,swing,Java,Swing,我试着旋转一个图像,但是当我旋转它的时候,它变得有点混乱,看起来它没有在中心旋转。所以如果我绕过去,它看起来像是被截断了。有没有更好的方法来获取图像的“中心” public void RotateImageLeft() { try { BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), originalImage.getType())

我试着旋转一个图像,但是当我旋转它的时候,它变得有点混乱,看起来它没有在中心旋转。所以如果我绕过去,它看起来像是被截断了。有没有更好的方法来获取图像的“中心”

public void RotateImageLeft() {
    try {
        BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), originalImage.getType());
        AffineTransform tx = new AffineTransform();
        tx.rotate(Math.toRadians(-90.0), originalImage.getWidth() / 2, originalImage.getHeight() / 2);



        Graphics2D g2 = newImage.createGraphics();
        g2.drawImage(originalImage, tx, null);

        originalImage = newImage;


        this.repaint();

        g2.dispose();
    } catch (Exception ex) {
        ex.toString();
    }


    //g2d.drawImage(getResImage(), rescale, x, y);


}
对于完整的代码公开,这里有更多的代码。以下是我的painComponent重写方法:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    resizeImage();

    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(getResImage(), rescale, x, y);


}
下面是调用的resizeImage()方法:

public void resizeImage() {
    Graphics g = getResImage().getGraphics();
    g.setColor(Color.WHITE);

    g.fillRect(0, 0, getResImage().getWidth(), getResImage().getHeight());
    int scaledWidth = (int) ((getOriginalImage().getWidth() * getHeight()
            / getOriginalImage().getHeight()));
    if (scaledWidth < getWidth()) {
        int leftOffset = getWidth() / 2 - scaledWidth / 2;
        int rightOffset = getWidth() / 2 + scaledWidth / 2;

        g.drawImage(getOriginalImage(),
                leftOffset, 0, rightOffset, getHeight(),
                0, 0, getOriginalImage().getWidth(), getOriginalImage().getHeight(),
                null);
    } else {
        int scaledHeight = (getOriginalImage().getHeight() * getWidth())
                / getOriginalImage().getWidth();

        int topOffset = getHeight() / 2 - scaledHeight / 2;
        int bottomOffset = getHeight() / 2 + scaledHeight / 2;

        g.drawImage(getOriginalImage(),
                0, topOffset, getWidth(), bottomOffset,
                0, 0, getOriginalImage().getWidth(), getOriginalImage().getHeight(),
                null);
    }
}
轮换后:

如果要旋转图像而不进行剪切,则需要首先在图像周围添加黑色条,因为旋转矩形的边界框总是比轴对齐矩形的边界框大(例外:将正方形旋转90度的倍数)


因此,您要做的是事先进行一些三角计算,以确定旋转图像的最大宽度/高度,并将其与原始宽度/高度相结合。使用这些尺寸调整图像大小(使其居中),旋转图像,然后将其裁剪回旋转图像的宽度/高度。

如果要旋转图像而不进行裁剪,则需要首先在图像周围添加黑色条,因为旋转矩形的边界框总是比轴对齐矩形的边界框大(例外:将正方形旋转90度的倍数)

因此,您要做的是事先进行一些三角计算,以确定旋转图像的最大宽度/高度,并将其与原始宽度/高度相结合。使用这些尺寸调整图像大小(居中),旋转图像,然后将其裁剪回旋转图像的宽度/高度。

从我的答案到

如果你在旋转,那么这个可以工作90度

  • 移动图像,使其以原点为中心
  • 无需额外参数的纯rotate()调用
  • 将图像移回中心,记住现在宽度=旧高度,高度=旧宽度
还要记住仿射变换步骤的工作顺序是相反的

AffineTransform tx = new AffineTransform();

// last, width = height and height = width
tx.translate(originalImage.getHeight() / 2,originalImage.getWidth() / 2);
tx.rotate(Math.PI / 2);
// first - center image at the origin so rotate works OK
tx.translate(-originalImage.getWidth() / 2,-originalImage.getHeight() / 2);
从我的回答到

如果你在旋转,那么这个可以工作90度

  • 移动图像,使其以原点为中心
  • 无需额外参数的纯rotate()调用
  • 将图像移回中心,记住现在宽度=旧高度,高度=旧宽度
还要记住仿射变换步骤的工作顺序是相反的

AffineTransform tx = new AffineTransform();

// last, width = height and height = width
tx.translate(originalImage.getHeight() / 2,originalImage.getWidth() / 2);
tx.rotate(Math.PI / 2);
// first - center image at the origin so rotate works OK
tx.translate(-originalImage.getWidth() / 2,-originalImage.getHeight() / 2);


我想我明白了,我只是个白痴。宽度/高度输入错误,只是为了确认吗?这种错误经常发生:是的,我只是注意到了。当我修复它时,它仍然在侧面添加黑色条,我不知道为什么。它没有截断任何东西,只是使图片看起来更小。是因为新图像是用与原始图像的宽度/高度相同?我对这些值进行了翻转(因为它正在旋转).但这导致了更多的问题。我想我明白了,我只是个白痴。宽度/高度输入错误,只是为了确认吗?这种错误经常发生:是的,我只是注意到了。当我修复它时,它仍然在两侧添加了黑色条带,我不知道为什么。它没有截断任何东西,只是让图片看起来更小。是因为创建的新图像的宽度/高度与原始图像相同?我对这些值进行了翻转(因为它正在旋转).但这导致了更多的问题。我只做了90º,我还需要添加黑条吗?我仍然认为这与旋转没有完全居中有关。是的,你仍然需要。如果你进行90度旋转,尺寸(w,h)的图像将变成尺寸(h,w)的图像。如果不在图像周围添加一些空间,将对其进行裁剪,您将只获得有效图像(min(w,h),min(w,h)),即在侧面或顶部/底部带有黑色边框的正方形(这是您的图像显示的).对,但即使我创建新图像作为旧图像的旋转版本,它仍然会创建黑色边框。我将编辑我的问题以显示我的意思…现在看起来它没有正确居中。看起来图像稍微被平移到图像的左上角,否则它会正确地匹配尺寸。奇怪的是,我会考虑它。我只做了90º,我还需要添加黑条吗?我仍然认为这与旋转没有完全居中有关。是的,你仍然需要。如果你做90度旋转,尺寸(w,h)的图像将变成尺寸(h,w)的图像。如果不在图像周围添加一些空间,将对其进行裁剪,您将只获得有效图像(min(w,h),min(w,h)),即在侧面或顶部/底部带有黑色边框的正方形(这是您的图像显示的).对,但即使我创建新图像作为旧图像的旋转版本,它仍然会创建黑色边框。我将编辑我的问题以显示我的意思…现在看起来它没有正确居中。看起来图像稍微被平移到图像的左上角,否则它会正确地匹配尺寸。奇怪的是,我会考虑它。那张奶牛图片是谷歌图片搜索结果。所有的奶牛图片都有正确的大小/纵横比。这个新程序将针对那些没有的奶牛,所以谷歌不得不填写,因为我懒得去手动拍摄奶牛。那张奶牛图片是谷歌图片搜索结果。所有的奶牛图片都有正确的大小/纵横比。这个新程序将我会支持那些不是的,所以谷歌不得不填写,因为我懒得去手动拍摄一头牛。