编程语言
首页 > 编程语言> > 在Java中将PNG图像快速加载到数组中

在Java中将PNG图像快速加载到数组中

作者:互联网

我想加载(和解码)PNG图像并将它们转换为Java中的一维数组.我显然可以使用ImageIO.read()然后将像素复制到数组中,但这会消耗两倍的内存(最终数组中的栅格),并且它涉及的处理时间比我想要的多.

我该怎么办呢?最坏的情况我可以自己实现PNG规范,但这似乎是一个相当复杂的任务.理想情况下,我想要一个可以“插入”的PNG实现.不太理想但仍然很好将是一个易于理解(不像com.sun代码)PNG阅读器,我可以(并将被允许)修改.

解决方法:

如果您要做的是将像素数据作为数组获取,那么您可以使用ImageIO.read()获取BufferedImage,然后使用BufferedImage.getRaster().getDataBuffer()来获取DataBuffer.从那里,您需要检查您拥有的BufferedImage类型,以确定如何转换DataBuffer.例如.如果你有一个TYPE_INT_RGB图像,那么你应该转换为DataBufferInt,然后你可以调用DataBufferInt.getData()来检索包含数据的int [].你用这种方式得到的不是副本 – 它是支持BufferedImage的实际数组.

但是,对于所有这些都有一个很大的警告:ImageIO.read()通常不会为您提供所需的图像类型.例如,你会经常得到TYPE_CUSTOM,除了复制到你真正想要的图像类型之外你不能做任何有用的事情.

因此,如果您足够幸运,ImageIO.read()会以您想要的格式提供图像,那么您将只能通过ImageIO.read()获取图像数据而无需再制作第二个副本.如果要检查ImageIO中可用的类型,可以调用ImageIO.getImageReaders()以获取声称能够读取流的所有读取器的Iterator,然后可以使用ImageReader.getImageTypes(0)获取读者可以阅读的图像类型的迭代器.您可能会找到一个能够以这种方式为您提供所需图像类型的阅读器,但请勿屏住呼吸.

除非您的图像很大,否则复制它们实际上非常快.但是,如果您的图像很大,则可能不得不求助于使用BufferedImage.getRGB()将原始图像数据一次写入磁盘一行(但是进行压缩,使用GZIPOutputStream),让原始图像为收集垃圾,创建所需类型的新BufferedImage,最后从磁盘读回行,使用BufferedImage.setRGB()将它们写入新映像. (几天前我写了一些东西来做这件事,因此我的想法中的细节相当新鲜.LGPL的来源是here.)

标签:java,png,performance,javax-imageio
来源: https://codeday.me/bug/20190717/1483893.html