Image 如何高效地从png流/文件中读取位图和元数据?
我需要使用[PNGJ]从PNG输入流解码位图和元数据(http://code.google.com/p/pngj/)图书馆。问题是,解码元数据将推进流,然后我无法使用 位图=BitmapFactory.decodeStream() 我自己创建位图是可以的,但如果我需要,比如说,用插值缩放位图,我宁愿使用BitmapFactory。要使用它,每次我必须使用PNGJ获取元数据和BitmapFactory获取位图时,我都必须创建InputStream的副本。从一个PNGJ调用返回元数据和位图会很好(至少对于最常见的ARGB_8888格式) 简而言之,我必须复制流以供Java库使用,这看起来像是浪费。返回位图将是一种解决方案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调用返回元数据和位图会很好(至
// 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