【问题标题】:Issue with reading Tiff image metadata with imageIO使用 imageIO 读取 Tiff 图像元数据的问题
【发布时间】:2013-08-09 15:09:08
【问题描述】:

我正在编写一个程序,它应该接收一堆 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) 在 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) 在 javax.imageio.stream.ImageInputStreamImpl.readUnsignedShort(ImageInputStreamImpl.java:242) 在 com.sun.media.imageioimpl.plugins.tiff.TIFFIFD.initialize(TIFFIFD.java:194) 在 com.sun.media.imageioimpl.plugins.tiff.TIFFImageMetadata.initializeFromStream(TIFFImageMetadata.java:110) 在 com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata(TIFFImageReader.java:336) ... 9 更多

我确实确保添加了正确的 JAI 库,并且我的阅读器使用的是“TIFF”类型,因此阅读器(和编写器)是正确的,但由于某种原因元数据是错误的。现在我可以在 Windows 中正常打开和查看所有这些图像,所以它们真的没有损坏或任何东西。 Java 只是不想正确阅读它们。由于我稍后只是使用流数据将它们写出来,所以我不太关心元数据,我只需要它在文件中读取到列表中,以便我可以附加它。我确实在 writer 上找到了 writer.replaceImageMetaData 方法,但 IOWriter 的 TIFFwriter 版本没有它的代码。我被困住了,有人吗?有没有办法读取部分元数据以查看错误并修复它?

【问题讨论】:

  • 你试过只读reader.getNumImages()吗?可能是TIFFImageReader 中的错误(可能在 IFD 解析器中),或者图像可能有错误/损坏的 IFD。如果可能的话,如果您发布指向其中一张引起问题的图片的链接可能会有所帮助。
  • 另外,如果您不需要元数据,为什么要readAll?不是一个简单的read 吗?
  • “geNumImages”有效,但简单的“读取”无效(这是我的第一次尝试)。问题是简单的读取也尝试读取元数据,因此它已损坏。我实际上发现了我的问题,我将在稍后发布我的解决方案。

标签: java tiff javax.imageio


【解决方案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;

}

我希望这对其他人有所帮助,因为我知道在这个问题上我找不到太多东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多