我有一个可以包含一个或多个图像的流,连续存储,没有任何标记。当我使用javas ImageIO打开并解析流时,它会正确解析第一个图像,但它会关闭流,这使我无法流式传输下一个图像。
所以我试图找出文件中每个压缩图像的大小,以便我可以将该图像的确切字节数读入缓冲区,从该缓冲区中创建ByteArrayInputStream,然后创建BufferedImage使用新的较小缓冲区。我的问题是弄清楚图像有多大,宽度/高度没有帮助,因为压缩比宽度*高度小。
有没有办法读取缓冲区并找出每个图像容易结束的位置?除了溪流末端的一个eof外,没有soi,eoi,sof,eof,标签。
或者有更好的方法吗? ImageIO.read()的一种方式,它不会关闭流并让我继续使用它?
答案 0 :(得分:0)
首先,tas_status
是一种便捷方法,它只能读取任何格式的任何文件的单个(第一个)图像。
相反,如果您获得输入的ImageIO.read(...)
,则可以(通常)使用ImageReader
获取输入中的图像数量,并使用{{读取(或跳过)单个图像1}}。
类似的东西:
getNumImages(boolean allowSearch)
JRE捆绑的read(int imageIndex, ImageReadParam param)
理论上也应支持单个流中的多个JFIF子流。但是,我认为您会发现支持被破坏(至少我的ImageIO插件项目中有open issue to fix this)。
不幸的是,找不到没有解码的JPEG压缩图像的长度(或者将长度存储在JFIF流之外)是不可能的。
您可以尝试的一件事是(可能包裹// Create input stream
try (ImageInputStream input = ImageIO.createImageInputStream(file)) {
// Get the reader
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
if (!readers.hasNext()) {
throw new IllegalArgumentException("No reader for: " + file);
}
ImageReader reader = readers.next();
try {
reader.setInput(input);
// Optionally, listen for read warnings, progress, etc.
reader.addIIOReadWarningListener(...);
reader.addIIOReadProgressListener(...);
ImageReadParam param = reader.getDefaultReadParam();
// Note: For some formats (ie. GIF), finding the number of images
// requires searching the entire stream. In this case, it may
// be more convenient to just read until you get an IndexOutOfBoundsException
for (int i = 0; i < reader.getNumImages(true); i++) {
// Optionally, control read settings like sub sampling, source region or destination etc.
param.setSourceSubsampling(...);
param.setSourceRegion(...);
param.setDestination(...);
// ...
// Finally read the image, using settings from param
BufferedImage image = reader.read(i, param);
// Optionally, read thumbnails, meta data, etc...
int numThumbs = reader.getNumThumbnails(0);
// ...
}
}
finally {
// Dispose reader in finally block to avoid memory leaks
reader.dispose();
}
}
)以读取第一张图像,然后向前扫描以获取下一张SOI(“图像开始”,{ {1}})标记,寻找两个字节(对于SOI标记)并尝试读取下一个图像。 SOI标记不能存在于JPEG编码数据中。
您可以在维基百科上阅读有关JPEG和JFIF segments的更多信息。