图像旋转方法在​​ram中留下了一些东西

时间:2015-06-02 20:08:15

标签: java memory bufferedimage affinetransform

我目前正在开发一款游戏,对于更多种类的图形我想调用一个旋转(BufferedImage imgOld,int deg)方法几百次来旋转一些图形(例如树桩)。

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

错误总是发生在旋转(BufferedImage imgOld,int deg)方法内部,并且只是因为我开始旋转大量图像所以我认为内存中必须有一些残留物来自旋转(BufferedImage imgOld,int deg方法我不知道如何处理。

在这里,您可以看到Rotator类的代码:

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

我希望有人有一个想法,我没有犯任何错误(这是我的第一个问题)。

2 个答案:

答案 0 :(得分:2)

您最大的问题很简单 - 您在每次旋转的时间内重复每个图像。您可以尝试将旋转后的图像绘制回自身,无需为垃圾收集器流过大量对象。

此外,如果您在创建新对象时设置不足,请确保刷新(BufferedImage#flush)旧图像并对图形对象进行dip(Graphics2D#dispose)。

答案 1 :(得分:0)

您使用错误的工具进行工作。如果你想转换整个图像,尤其是BufferedImage,你应该看一下BufferedImageOp和你的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°角度更大的图像,这似乎不是您想要的,给出你问题中的代码。