【发布时间】:2011-11-22 22:48:43
【问题描述】:
我将图像以 ImageIcons 的形式存储在数据库中,我想将这些图像提供给我们的网页,但是对于大图像,我会出现内存不足的异常。
这是我目前的做法,
[编辑]我扩展了我的 ImageUtilities 以提供一个非透明的 BufferedImage 来简化代码,
BufferedImage rgbbi = ImageUtilities.toBufferedImage(icon.getImage());
ServletOutputStream out = null;
try {
// Get the Servlets output stream.
out = responseSupplier.get().getOutputStream();
// write image to our piped stream
ImageIO.write(rgbbi, "jpg", out);
} catch (IOException e1) {
logger.severe("Exception writing image: " + e1.getMessage());
} finally {
try {
out.close();
} catch (IOException e) {
logger.info("Error closing output stream, " + e.getMessage());
}
}
抛出的异常如下,
Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
at java.awt.image.Raster.createPackedRaster(Raster.java:458)
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1015)
at sun.awt.image.ImageRepresentation.createBufferedImage(ImageRepresentation.java:230)
at sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:484)
at sun.awt.image.ImageDecoder.setPixels(ImageDecoder.java:120)
at sun.awt.image.JPEGImageDecoder.sendPixels(JPEGImageDecoder.java:97)
at sun.awt.image.JPEGImageDecoder.readImage(Native Method)
at sun.awt.image.JPEGImageDecoder.produceImage(JPEGImageDecoder.java:119)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:246)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space
...
有没有办法可以重写它以流式传输ImageIO.write 的输出并以某种方式限制其缓冲区大小?
[编辑]
我也不能只增加堆大小,我需要提供的图像在 10000x7000 像素的范围内,作为一个字节数组,计算出 (10000px x 7000px x 24bits)280MB。我认为为 servlet 中的图像转换分配的堆大小不合理。
示例图片Large
【问题讨论】:
-
很抱歉问了这么明显的问题,但您是否尝试过增加堆大小或将图像切成更小的块?
-
@kostja 我的图像的一个例子是 10368x6912 像素大,压缩后为 5Mb,未压缩在我认为不到 2Gb 的位置。另外,我怎样才能切一个 ImageIcon?
-
所以您将从服务器发送 2GB 数据?如果你有这样的带宽容量,你可以负担更多的 RAM 和 Java 堆。
-
@Andrew 我做错了数学:P,280MB 是正确的大小。该大小指的是BufferedImage,需要转换为转换后提供的jpeg,这是一个可管理的大小。
-
您真的需要在 servlet 中处理这些图像吗?因为这是个糟糕的主意。
标签: java image-processing awt