Image 如何高效地从png流/文件中读取位图和元数据?

Image 如何高效地从png流/文件中读取位图和元数据?,image,bitmap,png,metadata,Image,Bitmap,Png,Metadata,我需要使用[PNGJ]从PNG输入流解码位图和元数据(http://code.google.com/p/pngj/)图书馆。问题是,解码元数据将推进流,然后我无法使用 位图=BitmapFactory.decodeStream() 我自己创建位图是可以的,但如果我需要,比如说,用插值缩放位图,我宁愿使用BitmapFactory。要使用它,每次我必须使用PNGJ获取元数据和BitmapFactory获取位图时,我都必须创建InputStream的副本。从一个PNGJ调用返回元数据和位图会很好(至

我需要使用[PNGJ]从PNG输入流解码位图和元数据(http://code.google.com/p/pngj/)图书馆。问题是,解码元数据将推进流,然后我无法使用 位图=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) {
    ... 
    }
//注册辅助块名
PngChunk.factoryRegister(ThumbNailProvider.chunkID,chunkPROP.class);
//流阅读器
PngReader pngr=新PngReader(流内,“调试标签PNG读取器”);
ByteArrayOutputStream outputStream=新建ByteArrayOutputStream();
PngWriter pngw=新的PngWriter(输出流,pngr.imgInfo);
//复制预数据块
pngw.copyChunksFirst(pngr,chunkcopybehavior.COPY\u ALL\u SAFE);
//复制图像数据
对于(int row=0;row
这是两个独立的流消费者的问题,比如说
Class1.parse(inputStream)
Class2.decode(inputStream)
,我们希望他们使用相同的单个流;如果我们无法控制消费者如何享用流,那么它就没有简单优雅的解决方案()

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

就你的具体情况而言,我能想到的备选方案是:

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


2) 将PngReader用作InputFilterStream,以便它只解析元数据并将整个流传递给使用者。目前,如果不对PNGJ代码进行调整,这是不可能的。我会看一看,如果有人实现了这个功能,我会在这里发布。

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

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

就你的具体情况而言,我能想到的备选方案是:

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


2) 将PngReader用作InputFilterStream,以便它只解析元数据并将整个流传递给使用者。目前,如果不对PNGJ代码进行调整,这是不可能的。我会看一看,如果有人实现了这个功能,我会把它贴在这里。

如果你想帮助优化你的代码,请贴上你的代码:)如果你想帮助优化你的代码,请贴上你的代码:)非常感谢你的回答。只有在位图数据之前存储元数据,InputFilterStream才会工作,对吗?我还可以使用mark()/reset()函数稍微倒带一个流。目前,我要么复制流(效率不高),要么将其转换为InputFilterStream,该位置在BitmapFactory之后不会移动。decodeFileDescriptor()被称为:FileInputStream fs=(FileInputStream)mIS;java.io.FileDescriptor fd=fs.getFD()对不起,我想说的是:只有在位图数据之前存储元数据,InputFilterStream才会工作,对吗?我还可以使用mark()/reset()函数稍微倒带一个流。目前,我要么复制流(效率不高),要么将其转换到文件描述符中,该文件描述符的位置在BitmapFactory之后不会移动。decodeFileDescriptor()被称为:FileInputStream fs=(FileInputStream)mIS;java.io.FileDescriptor fd=fs.getFD()如果流来自一个文件,那么为什么不打开它两次呢?似乎是最简单有效的方法,特别是如果您希望PngJ只解析元数据的话。请记住,PngReader有一种方法在这种情况下非常有效。不,它不是来自文件,而是来自服务器。FileDescriptor解决方案允许以非破坏性方式读取流。非常感谢您的帮助性回答。只有在位图数据之前存储元数据,InputFilterStream才会工作,对吗?我还可以使用mark()/reset()函数稍微倒带一个流。目前,我要么复制流(效率不高),要么将其转换为InputFilterStream,该位置在BitmapFactory之后不会移动。decodeFileDescriptor()被称为:FileInputStream fs=(FileInputStream)mIS;java.io.FileDescriptor fd