Java,使用AffineTransform不能完全旋转居中

时间:2012-03-19 19:41:06

标签: java swing

我正在尝试旋转图像,但是当我旋转它时,它会稍微变得混乱,看起来它不会在中心旋转它。因此,如果我四处走动,它看起来就像是被截断了。有没有更好的方法来获得图像的“中心”?

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);
    }
}

我正在使用ResizeImage方法,因为我希望任何图像能够正确地放在我的720/432面板上。

这是一些示例图片。 预旋转  enter image description here

后轮换:

enter image description here

新代码:(新图像是旋转图像的正确高度/宽度,仍然会出现黑条。屏幕如下。

public void RotateImageLeft() {
    try {
        BufferedImage newImage = new BufferedImage( originalImage.getHeight(),originalImage.getWidth(), originalImage.getType());
        AffineTransform tx = new AffineTransform();
        tx.rotate(Math.toRadians(-90.0), newImage.getWidth() / 2, (newImage.getHeight() / 2));
        Graphics2D g2 = newImage.createGraphics();
        g2.drawImage(originalImage, tx, null);
        originalImage = newImage;
        this.repaint();
        g2.dispose();
    } catch (Exception ex) {
        ex.toString();
    }
}

旋转后: enter image description here

2 个答案:

答案 0 :(得分:3)

从我对another similar question

的回答

如果你正在旋转那么这将工作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);

答案 1 :(得分:1)

如果你想在没有裁剪的情况下旋转图像,你需要先在它周围添加黑条,因为旋转的矩形总是有一个比轴对齐的更大的边界框(例外:将一个正方形旋转90度的倍数)。

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