Java 图像旋转方法会在ram中留下一些内容
我目前正在开发一个游戏,为了获得更多的图形多样性,我想调用旋转(BuffereImage imgOld,int deg)方法数百次来旋转一些图形(例如树桩) 对于未旋转的图形,我从未遇到过任何内存问题。但是,当我开始使用旋转器时,如果我没有大幅减少旋转图像的数量(比如95%),就会出现错误 这个错误总是发生在rotate(BufferedImage-imgOld,int-deg)方法中,而且只是因为我开始旋转大量的图像,所以我想在rotate(BufferedImage-imgOld,int-deg)方法的内存中一定有一些剩余的东西,我不知道如何处理 在这里您可以看到类旋转器的代码:Java 图像旋转方法会在ram中留下一些内容,java,memory,bufferedimage,affinetransform,Java,Memory,Bufferedimage,Affinetransform,我目前正在开发一个游戏,为了获得更多的图形多样性,我想调用旋转(BuffereImage imgOld,int deg)方法数百次来旋转一些图形(例如树桩) 对于未旋转的图形,我从未遇到过任何内存问题。但是,当我开始使用旋转器时,如果我没有大幅减少旋转图像的数量(比如95%),就会出现错误 这个错误总是发生在rotate(BufferedImage-imgOld,int-deg)方法中,而且只是因为我开始旋转大量的图像,所以我想在rotate(BufferedImage-imgOld,int-d
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
)图形对象。你使用的作业工具不正确。如果您想转换整个图像,尤其是BufferedImage
s,您应该看看s和您的案例
然后,整个操作可以按照如下方式实现:
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);
}
这不适用于图形
等。原始方法的工作方式是旋转原始图像,并通过将目标的原始内容(最初为空)与源的旋转数据相结合,将其绘制到目标图像上,具体取决于图形
混合模式。相反,上面的代码将直接将转换后的图片渲染到目标中,而不是试图保留现有内容
请进一步注意,您可以传入现有映像以供重用。支持
null
destination image参数以创建新的兼容图像,但是AffineTransformOp
会创建一个大于源图像的图像,角度为45°,这似乎不是您想要的,考虑到您问题中的代码。是否保留对返回旋转图像的引用(例如,将它们存储在一个数组中)?是的,我将返回的旋转图像保存在对象中,这些对象保存在一个数组中,但它们会覆盖未旋转的图像,这将使内存与方法末尾的g.dispose();
和使用createGraphics()
将类型转换为Graphics2D
已过时。感谢您的快速响应-尽管添加了g,但很遗憾。dispose()
没有删除错误,但旧图像已替换为新图像。类似于image=Rotator.rotate(图像,度)
我应该如何以及在哪里刷新它?就在返回语句之前,调用g.dispose()
和imgOld.flush()
是我问题的解决方案-我仍然得到错误,但只是在大量的图形上,这是一个缺乏优化的问题。(每个图像都加载到ram中,尽管并非所有图像都在屏幕上可见)如果优化编码,则所有图像都应该工作无错误不知道这是否是一个问题,但通常人们会意外地制作多个buffereImage
s,而这样做很好。始终记住每个图像文件最多有一个对象。