AffineTransformOp速度/内存问题

时间:2009-12-03 17:44:54

标签: java filter affinetransform

我以前曾问过这个问题,但我想重新阐明/澄清一些观点并对其进行扩展。我有一段代码使用AffineTransform转换BufferedImage。

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage = op.filter(displayImage, null);

此代码工作正常,但它会导致内存累积。具体来说,每次调用这段代码时都会存储更多内存。我也尝试过其他形式的过滤器。

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage2 = op.createCompatibleDestImage(displayImage, displayImage.getColorModel());
op.filter(displayImage, displayImage2);

但是,这比第一个版本要慢得多。我希望第一个版本的速度与第二个版本的内存使用速度相同。

  1. 如何在第一个版本之后清理?具体来说,存储中间BufferedImages的位置,以及如何删除它们?
  2. 为什么第二个版本比第一个慢?我该怎么做才能加快速度?
  3. 感谢您的帮助!!!

2 个答案:

答案 0 :(得分:0)

我同意评论,除非你得到OutOfMemoryErrors,否则这是正常的事情,GC会在它认为合适时收集图像。这是一个愚蠢的测试,当我有一个问题时我有时做了:把它放在一个主函数的循环中,并在一个分析器中观察内存使用情况(它应该形成一个类似Z字形的模式或者其他东西)但是并不总是能够完成成功。

答案 1 :(得分:0)

您如何获得displayImage以及ColorModel使用的是什么?

如果是IndexColorModel,可能会解释很多。

第一个代码片段将使用BufferedImage返回DirectColorModel。对于索引图像,这将需要每像素4个字节,而每像素通常需要1个字节。 1:4的扩展可能导致你的内存不足。

第二个代码片段使BufferedImage与源具有相同的模型。当该值为IndexColorModel且插值不是NEAREST_NEIGHBOR时,filter()调用将创建一个BufferedImage的临时DirectColorModel。它将使用它作为过滤器操作的目标,然后重新量化临时缓冲区并将其绘制到displayImage2中。所以,bitblits的数量是原来的两倍。

如果你只进行一次转换,我会说第二种形式。

如果您正在进行多项操作,请分配一对BufferedImageDirectColorModel。大到足以容纳你最大的形象。将源图像绘制到其中一个中,然后在它们之间来回执行过滤。然后,当您完成后,使用ColorConvertOp重新量化回索引图像。这样,您只需要进行一次颜色转换,而不是每次过滤调用。