Проблема с чтением метаданных изображения Tiff с помощью imageIO

Я пишу программу, которая должна собрать кучу мелочей и собрать их воедино. Я заставил его работать с большинством файлов изображений, которые я читал, но большая их партия выдает ошибку, когда я пытаюсь их прочитать.

Вот фрагмент кода, который у меня есть:

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

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

Да, я улавливаю исключение за пределами поля, поэтому нам не о чем беспокоиться. Моя проблема в том, что я получаю следующую ошибку:

javax.imageio.IIOException: ошибка ввода-вывода при чтении метаданных изображения! на com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.readMetadata (TIFFImageReader.java:340) на com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.seekToImage (TIFFImage.sun10) atjava. .media.imageioimpl.plugins.tiff.TIFFImageReader.prepareRead (TIFFImageReader.java:971) по адресу com.sun.media.imageioimpl.plugins.tiff.TIFFImageReader.read (TIFFImageReader.java:1153ageio.java.Reader.java:1153) в java.avax.image (ImageReader.java:1067) на sel.image.appender.ImageAppender.mergeImages (ImageAppender.java:59) на sel.imagenow.processor.AetnaLTCProcessor.processBatch (AetnaLTCProcessor.java:287) по адресу sel.imagenow.processor.Aetorna. 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.sioplmedia) в .plugins.tiff.TIFFIFD.initialize (TIFFIFD.java:194) по адресу com.sun.media.imageioimpl.plugins.tiff.TIFFImageMetadata.initializeFromStream (TIFFImageMetadata.java:110) по адресу com.sio.media.pl .TIFFImageReader.readMetadata (TIFFImageReader.java:336) ... еще 9

Я обязательно добавил правильную библиотеку JAI, и мой читатель использует тип "TIFF", поэтому читатель (и писатель) верны, но по какой-то причине метаданные неверны. Теперь я могу нормально открывать и просматривать все эти изображения в Windows, чтобы они не были повреждены или что-то в этом роде. Java просто не хочет их правильно читать. Поскольку я просто использую потоковые мясные данные, чтобы записать их позже, меня не очень волнуют метаданные, мне просто нужно, чтобы они были прочитаны в файле в списке, чтобы я мог добавить их. Я нашел метод writer.replaceImageMetaData на писателе, но в версии IOWriter для TIFFwriter нет кода для него. Я застрял, кто-нибудь что-нибудь? Может быть, есть способ прочитать части метаданных, чтобы увидеть, что не так, и исправить это?


person user940769    schedule 09.08.2013    source источник
comment
Вы пробовали читать только reader.getNumImages()? Может быть ошибка в TIFFImageReader (возможно, в парсере IFD) или изображение могло иметь плохой / поврежденный IFD. Если возможно, это может помочь, если вы разместите ссылку на одно из изображений, вызывающих проблемы.   -  person Harald K    schedule 12.08.2013
comment
Кроме того, почему readAll, если вам не нужны метаданные? Разве простой read не годится?   -  person Harald K    schedule 12.08.2013
comment
«GeNumImages» работал, но простое «чтение» - нет (это была одна из моих первых попыток). Проблема в том, что простое чтение также пытается прочитать метаданные, поэтому они были повреждены. Я действительно понял свою проблему, и я собираюсь опубликовать свое решение немного позже.   -  person user940769    schedule 13.08.2013


Ответы (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;

}

Я надеюсь, что это поможет кому-то другому, потому что я знаю, что по этой проблеме я не так много смогу найти.

person user940769    schedule 13.08.2013