0

我以前问过这个问题,但我想改写/澄清一些观点并对其进行扩展。我有一段代码使用 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. 为什么第二个版本比第一个慢?我该怎么做才能加快速度?

谢谢你的帮助!!!

4

2 回答 2

0

I agree with the comment that unless you're getting OutOfMemoryErrors, then this is a normal thing and the GC will collect the images whenever it sees fit. Here's a silly test I did sometimes when I had a concern: put that into loop in a main function and watch the memory usage in a profiler (it should make a zig-zag-like pattern or something) but not always be able to complete successfully.

于 2009-12-03T18:36:09.017 回答
0

你是怎么得到的displayImageColorModel它在用什么?

如果它是一个IndexColorModel,那可能会解释很多。

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

第二个代码片段BufferedImage与源代码具有相同的模型。当那是 anIndexColorModel而插值不是NEAREST_NEIGHBOR时,filter()调用将创建一个BufferedImage带有 a的临时对象DirectColorModel。它将使用它作为过滤器操作的目标,然后重新量化临时缓冲区并将其绘制到您的displayImage2. 所以,比特位的两倍。

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

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

于 2009-12-03T21:20:19.560 回答