【问题标题】:Circumventing ImageIO.write's slowness规避 ImageIO.write 的缓慢性
【发布时间】:2013-09-26 23:45:31
【问题描述】:

我最近发现我正在使用的 ImageIO 库正在将图像写入字节数组/流的速度非常慢,并且从

BufferedImage img;//initialized elsewhere
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img,"png",baos);

BufferedImage img;//initialized elsewhere
byte[] argb = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();

虽然第二种方法快了近 70 倍,但我找不到从这个 argb 字节数组重新创建 BufferedImage 的快速方法。

【问题讨论】:

  • 我把它读回来类似于你的旧 impl 不是一个选项?
  • 之前我使用 ImageIO.read 将其读回,但这取决于已使用 ImageIO.write 编码的字节流。第二个代码示例中的字节数组只是所有像素值的转储,而不是编码的字节流。
  • 那会不会让它成为一个简单的 BMP 呢?这应该可以做这样的事情 - stackoverflow.com/questions/4234703/… 或者这个 - stackoverflow.com/questions/6319465/…
  • 标准 Java ImageIO PNG 编写器速度慢似乎是一个常见问题。尝试用谷歌搜索“fast png decoder java”,你会发现一些替代品,比如 objectplanet、fastpng 和 Sixlegs。您是否尝试过编写另一种格式(如 BMP)?在任何情况下,您都可以从原始像素重新创建您的图像(已经有很多关于它的问题),但您需要知道通常存储在文件格式标题中的颜色模型、宽度、高度等信息。
  • PS:只是想指出第二个数组中的代码不是像素的转储,它是像素。代码非常快,因为它只是一个单一的任务。您可以从这些像素创建新图像,但如果您在不复制的情况下这样做(这需要更多时间),对一个图像的更改将反映在另一个图像中。

标签: java javax.imageio raster


【解决方案1】:

好吧,我并不是说传递原始像素通常是一个好主意,但它可能适合这个特定的用例。

根据cmet中的讨论,应该是这么难的:

DataBuffer buffer = new DataBufferByte(argb, argb.length); // arg is your input array
ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8, 8}, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);

return new BufferedImage(cm, Raster.createInterleavedRaster(buffer, width, height, width * 4, 4, new int[] {0, 1, 2, 3}, null), false, null);

所有假设您在 argb 数组中确实有 ARGB 像素,并且 widthheight 是已知的。使所有数组和颜色模型保持不变以获得更好的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 2015-01-27
    • 2021-06-04
    • 2016-11-09
    相关资源
    最近更新 更多