图像旋转方法在​​内存中留下一些东西

image rotation method leaves something in the ram

我目前正在开发一款游戏,为了获得更多样化的图形,我想调用 rotate(BufferedImage imgOld, int deg) 方法数百次来旋转一些图形(例如树桩)。

对于未旋转的图形,我从未遇到过任何内存问题。但是,一旦我开始使用旋转器,如果我没有大幅减少旋转图像的数量(比如大幅减少 95%),就会发生错误。

错误总是发生在 rotate(BufferedImage imgOld, int deg) 方法内部,并且只是因为我开始旋转大量图像,所以我想内存中一定有一些来自 rotate(BufferedImage imgOld, int deg) 方法我不知道怎么处理。

在这里你可以看到 class 旋转器的代码:

package movement;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

public class Rotator {
    public static BufferedImage rotate(BufferedImage imgOld, int deg){                                                                              //Parameters for the method are the image to rotate and the rate of rotation in degrees
        AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(deg), (int)(imgOld.getWidth()/2), (int)(imgOld.getHeight()/2));       //setting up the transform
        BufferedImage imgNew = new BufferedImage(imgOld.getWidth(), imgOld.getHeight(), imgOld.getType());                                          //creating a new image with the same properties of the old one
        Graphics2D g = (Graphics2D) imgNew.getGraphics();                                                                                           //create my graphics
        g.setTransform(at);                                                                                                                         //applying the transform
        g.drawImage(imgOld, 0, 0, null);                                                                                                            //painting rotated image
        return imgNew;                                                                                                                              //return rotated image              
    }       
}

我希望有人有想法并且我没有犯任何错误(这是我在这里发布的第一个问题)。

您最大的问题很简单 - 您正在复制 个图像,您 次旋转。您可以尝试将旋转后的图像绘制回自身,从而无需为垃圾收集器搅动大量对象。

此外,如果您执意要制作新对象,请确保冲洗 (BufferedImage#flush) 旧图像并丢弃 (Graphics2D#dispose) 图形对象。

您使用的工具错误。如果你想转换整个图像,尤其是。 BufferedImages,你应该看看BufferedImageOps and in your case AffineTransformOp

那么整个操作可以实现为

public static BufferedImage rotate(BufferedImage imgOld, int deg){
    AffineTransform at = AffineTransform.getRotateInstance(
        Math.toRadians(deg), imgOld.getWidth()/2, imgOld.getHeight()/2);
    AffineTransformOp op=new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
    BufferedImage imgNew = new BufferedImage(
        imgOld.getWidth(), imgOld.getHeight(), imgOld.getType());
    return op.filter(imgOld, imgNew);
}

这不涉及 Graphics 之类的。您最初的方法是旋转原始图像并将其绘制到目标图像上,方法是将目标的原始内容(最初为空)与源的旋转数据相结合,具体取决于 Graphics 混合模式。相比之下,上面的代码会将转换后的图片直接渲染到目标中,而不是试图保留现有内容。

进一步注意,您可以传入现有图像以供重复使用。 BufferedImageOp.filter 支持 null 目标图像参数以创建新的兼容图像,但 AffineTransformOp 会创建比源图像更大的角度,例如 45°,这似乎不是您想要的,给出你问题中的代码。