我正在编写一个应该收集一堆tiff并将它们组合在一起的程序。我把它用于我读过的大多数图像文件,但是当我尝试读取它们时,大量的图像文件都会抛出错误。
以下是我的代码片段:
int numPages = 0;
inStream = ImageIO.createImageInputStream(imageFile);
reader.setInput(inStream);
while(true){
bufferedImages.add(reader.readAll(numPages, reader.getDefaultReadParam()));
numPages++;
}
是的,我抓住了出界的例外,所以我们不必担心。我的问题是我收到以下错误:
javax.imageio.IIOException:读取图像元数据的I / O错误! 在com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata(TIFFImageReader.java:340) at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.seekToImage(TIFFImageReader.java:310) 在com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.prepareRead(TIFFImageReader.java:971) 在com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.read(TIFFImageReader.java:1153) 在javax.imageio.ImageReader.readAll(ImageReader.java:1067) 在sel.image.appender.ImageAppender.mergeImages(ImageAppender.java:59) 在sel.imagenow.processor.AetnaLTCProcessor.processBatch(AetnaLTCProcessor.java:287) 在sel.imagenow.processor.AetnaLTCProcessor.processImpl(AetnaLTCProcessor.java:81) 在sel.processor.AbstractImageNowProcessor.process(AbstractImageNowProcessor.java:49) 在sel.RunConverter.main(RunConverter.java:37)
引起:java.io.EOFException 在javax.imageio.stream.ImageInputStreamImpl.readShort(ImageInputStreamImpl.java:229) at javax.imageio.stream.ImageInputStreamImpl.readUnsignedShort(ImageInputStreamImpl.java:242) 在com.sun.media.imageioimpl.plugins.tiff.TIFFIFD.initialize(TIFFIFD.java:194) at com.sun.media.imageioimpl.plugins.tiff.TIFFImageMetadata.initializeFromStream(TIFFImageMetadata.java:110) at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata(TIFFImageReader.java:336) ... 9更多
我确实添加了正确的JAI lib,我的读者正在使用" TIFF"类型,所以读者(和作家)是正确的但由于某种原因元数据是错误的。现在我可以在Windows中打开并查看所有这些图像,这样它们确实没有被破坏或者任何东西。 Java只是不想在右边阅读它们。由于我以后只是使用流数据库来编写它们,所以我不太关心我只需要将文件读入列表的元数据,以便我可以追加它。我确实在编写器上找到了writer.replaceImageMetaData方法,但IOWriter的TIFFwriter版本没有代码。我被卡住了,还有什么事吗?有没有办法读取部分元数据以查看错误并修复它?
答案 0 :(得分:1)
对于任何想知道的人,我最终解决了自己的问题。看来图像元数据有点搞砸了。由于我只是进行了简单的合并,因为我知道每个图像都是一个页面,所以我能够使用缓冲图像来读取图片,然后使其成为具有空元数据的IIOImage。我使用流元数据(工作)来合并图像。这是我用来合并图像列表的完整方法:
public static File mergeImages(List<File> files, String argID, String fileType, String compressionType) throws Exception{
//find the temp location of the image
String location = ConfigManager.getInstance().getTempFileDirectory();
logger_.debug("image file type [" + fileType + "]");
ImageReader reader = ImageIO.getImageReadersByFormatName(fileType).next();
ImageWriter writer = ImageIO.getImageWritersByFormatName(fileType).next();
//set up the new image name
String filePath = location + "\\" + argID +"." + fileType;
//keeps track of the images we copied from
StringBuilder builder = new StringBuilder();
List<IIOImage> bufferedImages = new ArrayList<IIOImage>();
IIOMetadata metaData = null;
for (File imageFile:files) {
//get the name for logging later
builder.append(imageFile.getCanonicalPath()).append("\n");
if (metaData == null){
reader.setInput(ImageIO.createImageInputStream(imageFile));
metaData = reader.getStreamMetadata();
}
BufferedImage image = ImageIO.read(imageFile);
bufferedImages.add(new IIOImage(image, null, null));
}
ImageWriteParam params = writer.getDefaultWriteParam();
if (compressionType != null){
params.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
params.setCompressionType(compressionType);
}
ImageOutputStream outStream = null;
try{
outStream = ImageIO.createImageOutputStream(new File(filePath));
int numPages = 0;
writer.setOutput(outStream);
for(IIOImage image:bufferedImages){
if (numPages == 0){
writer.write(metaData, image, params);
}
else{
writer.writeInsert(numPages, image, params);
}
numPages++;
}
}
finally{
if (outStream != null){
outStream.close();
}
}
//set up the file for us to use later
File mergedFile = new File(filePath);
logger_.info("Merged image into [" + filePath + "]");
logger_.debug("Merged images [\n" + builder.toString() + "] into --> " + filePath);
return mergedFile;
}
我希望这可以帮助别人,因为我知道在这个问题上我找不到多少。