1

我需要使用 [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) {
    ... 
    }
4

1 回答 1

1

这就是有两个独立的流消费者的问题,比如说Class1.parse(inputStream)Class2.decode(inputStream)我们希望他们消费同一个流;如果我们无法控制消费者如何吃流,它就没有简单优雅的解决方案(例如)。

简单的解决方案,但不是很优雅 - 并且可能不切实际 - 是:关闭并重新打开流(如果我们从网络流中读取,则不可行),将完整的流内容缓冲到内存中,或临时文件。

在您的具体情况下,我能想到的替代方案是:

1)让PNGJ消费和解码数据并自己创建位图,用setPixels()填充像素。除其他不便外,这还需要您进行正确的颜色转换。

2) 使用 PngReader 作为 InputFilterStream,使其只解析元数据并将完整的流传递给消费者。目前,如果不对 PNGJ 代码进行调整,这是不可能的。我会看一下,如果实现此功能,我将在此处发布。

于 2012-12-29T16:03:38.423 回答