Java2D - 如何旋转图像并保存结果

3
我正在制作一个游戏,其中一些物体会旋转以面对它们射击的目标。在射击之间有一个延迟,我希望物体保持面向其所在位置,直到再次射击。我知道如何加载图像,并且知道如何使用AffineTransform旋转它们。但是,这样做需要每次绘制对象时重新计算旋转。
因此,我的问题是如何旋转图像并将结果保存到新图像中以进行显示?
3个回答

3
Affline transform(仿射变换)只适用于完全平方的图像。以下代码用于将任意矩形图像正确旋转。为此,它选择一个中心点,该中心点是较长一侧的一半,并欺骗库认为图像是完美的正方形,然后执行旋转并告诉库在哪里找到正确的左上角点。每个方向上的特殊情况发生在旋转的图像的左侧或顶部不存在额外图像的情况下。在这两种情况下,点通过较长边和较短边之间的差异进行调整,以获得图像的正确左上角。注意:x轴和y轴也随图像旋转,因此在width>height时,调整总是在y轴上发生,在height>width时,调整发生在x轴上。
private BufferedImage rotate(BufferedImage image, double _theta, int _thetaInDegrees) {

    AffineTransform xform = new AffineTransform();

    if (image.getWidth() > image.getHeight()) {
        xform.setToTranslation(0.5 * image.getWidth(), 0.5 * image.getWidth());
        xform.rotate(_theta);

        int diff = image.getWidth() - image.getHeight();

        switch (_thetaInDegrees) {
            case 90:
                xform.translate(-0.5 * image.getWidth(), -0.5 * image.getWidth() + diff);
                break;
            case 180:
                xform.translate(-0.5 * image.getWidth(), -0.5 * image.getWidth() + diff);
                break;
            default:
                xform.translate(-0.5 * image.getWidth(), -0.5 * image.getWidth());
                break;
        }
    } else if (image.getHeight() > image.getWidth()) {
        xform.setToTranslation(0.5 * image.getHeight(), 0.5 * image.getHeight());
        xform.rotate(_theta);

        int diff = image.getHeight() - image.getWidth();

        switch (_thetaInDegrees) {
            case 180:
                xform.translate(-0.5 * image.getHeight() + diff, -0.5 * image.getHeight());
                break;
            case 270:
                xform.translate(-0.5 * image.getHeight() + diff, -0.5 * image.getHeight());
                break;
            default:
                xform.translate(-0.5 * image.getHeight(), -0.5 * image.getHeight());
                break;
        }
    } else {
        xform.setToTranslation(0.5 * image.getWidth(), 0.5 * image.getHeight());
        xform.rotate(_theta);
        xform.translate(-0.5 * image.getHeight(), -0.5 * image.getWidth());
    }

    AffineTransformOp op = new AffineTransformOp(xform, AffineTransformOp.TYPE_BILINEAR);

    return op.filter(image, null);
}

3
如何旋转图像并保存结果到一个新的图像中以便显示?
创建一个新的BufferedImage。通过 BufferedImage.getGraphics() 获取一个 Graphics 对象。将旋转后的图像绘制到这个缓冲图像上,并将图像根据其旋转角度保存在数组或映射中(这样在需要时就可以轻松查找它)。

谢谢您的迅速回复。我是否应对所有360度进行旋转?由于图像相对较小,每2或5度拍摄一次是否同样有效? - Jonathan
如果我是你,我会将其设置为编译时常量,比如NUM_ROTATIONS,并创建一个 BufferedImage[NUM_ROTATIONS] 数组来存储精灵,并通过 i * 360.0 / NUM_ROTATIONS 旋转每个精灵。这样你就可以轻松地尝试不同的旋转效果了。 - aioobe
很快你就能做到了 :-) - aioobe

1
尝试像这样克隆图像:
BufferedImage source = new BufferedImage(50, 10, BufferedImage.TYPE_4BYTE_ABGR); 

BufferedImage target = new BufferedImage(50, 10, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D tg = target.createGraphics();

AffineTransform at = new AffineTransform();
at.rotate(2);

tg.drawImage(source, at, null);

抱歉,忽略我之前的回答,我误读了问题。对不起。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接