我需要使用[PNGJ](http://code.google.com/p/pngj/)库从PNG输入流解码位图和元数据。问题是解码元数据会推进流然后我无法使用 bitmap = BitmapFactory.decodeStream()。
我自己创建位图是可以的但是如果我需要比如使用插值来缩放位图,我宁愿使用BitmapFactory。要使用它,每次我必须使用PNGJ获取元数据和BitmapFactory来获取位图时,我必须创建一个InputStream副本。从单个PNGJ调用返回元数据和位图会很好(至少对于最常见的ARGB_8888格式)。
简而言之,我必须复制Java库使用的流,这看起来像是浪费。返回位图将是一种解决方案。
// register an auxilary chunk name
PngChunk.factoryRegister(ThumbNailProvider.chunkID, chunkPROP.class);
// reader for the stream
PngReader pngr = new PngReader(inStream, "debug label PNG reader");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PngWriter pngw = new PngWriter(outputStream, pngr.imgInfo);
// copy pre-data chunks
pngw.copyChunksFirst(pngr, ChunkCopyBehaviour.COPY_ALL_SAFE);
// copy image data
for (int row = 0; row < pngr.imgInfo.rows; row++) {
ImageLine l1 = pngr.readRow(row);
pngw.writeRow(l1, row);
}
// copy after-data chunks
pngw.copyChunksLast(pngr, ChunkCopyBehaviour.COPY_ALL);
pngr.end(); // close inStream but not its copy
pngw.end(); // close out stream
// save a copy of the stream for Java Libraries;
data.inputStream = new ByteArrayInputStream(outputStream.toByteArray());
// read the chunk
ChunksList chunkList = pngr.getChunksList();
PngChunk chunk = chunkList.getById1(L2ThumbNailProvider.chunkID);
if (chunk != null) {
...
}
答案 0 :(得分:1)
这就是拥有两个独立的流消费者的问题,比如Class1.parse(inputStream)
,Class2.decode(inputStream)
,我们希望他们使用相同的单个流;它没有简单优雅的解决方案(eg),如果我们无法控制消费者如何吃流。
简单的解决方案,但不是非常优雅 - 并且可能不切实际 - 是:关闭并重新打开流(如果我们从网络流中读取则不可行),缓冲内存中的完整流内容或临时文件。
在具体案例中,我能想到的替代方案是:
1)让PNGJ使用和解码数据并自己创建位图,用setPixels()填充像素。除了其他不便之外,还需要您进行适当的颜色转换。
2)使用PngReader作为InputFilterStream,以便它只解析元数据并将完整的流传递给使用者。目前,如果不对PNGJ代码进行调整,这是不可能的。我将介绍一下,如果实现此功能,我将在此处发布。