繁体   English   中英

使用imageIO读取Tiff图像元数据时出现问题

[英]Issue with reading Tiff image metadata with imageIO

我正在编写一个程序,该程序应该吸收一堆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) java.imageio.ImageReader.readAll上的.media.imageioimpl.plugins.tiff.TIFFImageReader.prepareRead(TIFFImageReader.java:971)位于com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.read(TIFFImageReader.java:1153) (ImageReader.java:1067),位于sel.image.appender.ImageAppender.mergeImages(ImageAppender.java:59),位于sel.imagenow.processor.AetnaLTCProcessor.processBatch(AetnaLTCProcessor.java:287),位于sel.imagenow.processor.AetnaLTCProcessor。在sel.RunConverter.main(RunConverter.java:37)处的processImpl(AetnaLTCProcessor.java:81)在sel.processor.AbstractImageNowProcessor.process(AbstractImageNowProcessor.java:49)

引起原因:javax.imageio.stream.ImageInputStreamImpl.readShort(ImageInputStreamImpl.java:229)处的java.io.EOFException com.sun.media.imageioimpl处的javax.imageio.stream.ImageInputStreamImpl.readUnsignedShort(ImageInputStreamImpl.java:242) com.sun.media.imageioimpl.plugins.tiff.TIFFImageMetadata.initializeFromStream(TIFFImageMetadata.java:110)上的com.sun.media.imageioimpl.plugins.tiff的.plugins.tiff.TIFFIFD.initialize(TIFFIFD.java:194) .TIFFImageReader.readMetadata(TIFFImageReader.java:336)...还有9个

我确实确保添加了正确的JAI库,并且我的读者使用的是“ TIFF”类型,因此读者(和作家)是正确的,但是由于某种原因元数据是错误的。 现在,我可以正常在Windows中打开并查看所有这些图像,这样它们就不会损坏或什么都没有。 Java只是不想正确阅读它们。 由于我只是在稍后使用流Meatadata将其写出,所以我不太在乎元数据,我只需要元数据将其读入列表中即可添加它。 我确实在writer上找到了writer.replaceImageMetaData方法,但是IOWriter的TIFFwriter版本没有相应的代码。 我被卡住了,有人吗? 也许有一种方法可以读取部分元数据来查看错误并进行修复吗?

对于任何想知道的人,我最终都解决了自己的问题。 图像的元数据似乎有点搞砸了。 因为我只是在进行纯合并,并且因为我知道每个图像都是一页,所以我能够使用缓冲的图像读取图片,然后将其设置为具有空元数据的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;

}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM