简体   繁体   English

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

[英]Issue with reading Tiff image metadata with imageIO

I'm writing a program that is supposed to taking in a bunch of tiff's and put them together. 我正在编写一个程序,该程序应该吸收一堆tiff并将它们放在一起。 I got it to work for most of the image files I read in but a large batch of them throw out an error when I try to read them in. 我可以将它用于读取的大多数图像文件,但是当我尝试读取它们时,其中很大一部分抛出了错误。

Here is a snippet of code I have: 这是我的一小段代码:

int numPages = 0;           
inStream = ImageIO.createImageInputStream(imageFile);
reader.setInput(inStream);

while(true){
    bufferedImages.add(reader.readAll(numPages, reader.getDefaultReadParam()));
    numPages++;
}

Yes I catch the out of bounds exception so we don't have to worry about that. 是的,我捕获了超出范围的异常,因此我们不必为此担心。 My problem is that I get the following error: 我的问题是出现以下错误:

javax.imageio.IIOException: I/O error reading image metadata! javax.imageio.IIOException:读取图像元数据时发生I / O错误! at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata(TIFFImageReader.java:340) at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.seekToImage(TIFFImageReader.java:310) at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.prepareRead(TIFFImageReader.java:971) at com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.read(TIFFImageReader.java:1153) at javax.imageio.ImageReader.readAll(ImageReader.java:1067) at sel.image.appender.ImageAppender.mergeImages(ImageAppender.java:59) at sel.imagenow.processor.AetnaLTCProcessor.processBatch(AetnaLTCProcessor.java:287) at sel.imagenow.processor.AetnaLTCProcessor.processImpl(AetnaLTCProcessor.java:81) at sel.processor.AbstractImageNowProcessor.process(AbstractImageNowProcessor.java:49) at sel.RunConverter.main(RunConverter.java:37) 在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)

Caused by: java.io.EOFException at javax.imageio.stream.ImageInputStreamImpl.readShort(ImageInputStreamImpl.java:229) at javax.imageio.stream.ImageInputStreamImpl.readUnsignedShort(ImageInputStreamImpl.java:242) at 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 more 引起原因: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个

I did make sure to add in the right JAI lib and my reader is using the "TIFF" type so the reader (and writer) is correct but for some reason the metadata is wrong. 我确实确保添加了正确的JAI库,并且我的读者使用的是“ TIFF”类型,因此读者(和作家)是正确的,但是由于某种原因元数据是错误的。 Now I can open and view all these images normally in windows so they really aren't corrupted or anything. 现在,我可以正常在Windows中打开并查看所有这些图像,这样它们就不会损坏或什么都没有。 Java just doesn't want to read them in right. Java只是不想正确阅读它们。 Since I'm just using the stream meatadata to write them out later I don't care that much about the metadata I just need it to read in the file to the list so I can append it. 由于我只是在稍后使用流Meatadata将其写出,所以我不太在乎元数据,我只需要元数据将其读入列表中即可添加它。 I did find a writer.replaceImageMetaData method on the writer but the TIFFwriter version of IOWriter doens't have code for it. 我确实在writer上找到了writer.replaceImageMetaData方法,但是IOWriter的TIFFwriter版本没有相应的代码。 I'm stuck, anyone anything? 我被卡住了,有人吗? Is there maybe a way to read in parts of the metadata to see what is wrong and fix it? 也许有一种方法可以读取部分元数据来查看错误并进行修复吗?

For anyone that would like to know I ended up fixing my own issue. 对于任何想知道的人,我最终都解决了自己的问题。 It seems the the image metadata was a bit screwed up. 图像的元数据似乎有点搞砸了。 Since I was just doing a plain merge and since I knew each image was one page I was able to use a buffered image to read in the picture then make it a IIOImage with null metadata. 因为我只是在进行纯合并,并且因为我知道每个图像都是一页,所以我能够使用缓冲的图像读取图片,然后将其设置为具有空元数据的IIOImage。 I used the stream metadata (which worked) to merge the images. 我使用了流元数据(有效)来合并图像。 Here is my complete method I use to merge a list of images: 这是我用来合并图像列表的完整方法:

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;

}

I hope this help someone else because I know there isn't much on this issue that I could find. 我希望这对其他人有帮助,因为我知道在这个问题上我找不到很多东西。

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

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