Ошибка при попытке прочитать регион из очень большого файла изображения в Java

Мне нужно прочитать очень большой файл изображения (56000 пикселей х 49000 пикселей). Мне нужно прочитать его небольшими прямоугольными порциями, поэтому я пытаюсь следовать этому примеру: чтение области из очень большого файла изображения на Java

Однако я получаю эту ошибку: java.lang.IllegalArgumentException: ширина * высота> Integer.MAX_VALUE!

Мой фрагмент кода ниже (взят более или менее точно по ссылке выше):

ImageInputStream stream = null;
    try {
        stream = ImageIO.createImageInputStream(new File(this.inFile)); // File or input stream
    } catch (Exception ex) {
        Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
    }
    Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);

    ImageReader r = readers.next();
    System.out.println("Using reader: " + r);
    r.setInput(stream);
    try {
        System.out.println("Height = " + r.getHeight(0));
        System.out.println("Width = " + r.getWidth(0));
    } catch (IOException ex) {
        Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
    }

ImageReadParam param = r.getDefaultReadParam();
Rectangle sourceRegion = new Rectangle(0, 0, 200, 200);
param.setSourceRegion(sourceRegion); // Set region

        BufferedImage image = null;
        try {
            image = r.read(0, param); // Will read only the region specified
            System.out.println("Read file " + this.inFile);
            System.out.println("Width = " + image.getWidth());
            System.out.println("Height = " + image.getHeight());
        } catch (Exception ex) {
            Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
        }

Насколько я понимаю, указание Rectangle sourceRegion для param приведет к тому, что ImageReader прочитает только этот маленький фрагмент изображения, поэтому я не понимаю, что является причиной ошибки. Любая помощь приветствуется. Если это поможет, я использую плагины TwelveMonkeys ImageIO.

Вот вывод:

Using reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@5437dd04
Height = 49429
Width = 56281
Apr 23, 2017 11:57:17 AM createtrainingsetfromimage.CreateTrainingSetFromImage    test
SEVERE: null
java.lang.IllegalArgumentException: width*height > Integer.MAX_VALUE!
at javax.imageio.ImageReader.getDestination(ImageReader.java:2840)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1066)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1034)
at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:382)
at createtrainingsetfromimage.CreateTrainingSetFromImage.test(CreateTrainingSetFromImage.java:102)
at createtrainingsetfromimage.CreateTrainingSetFromImage.createTrainingSet(CreateTrainingSetFromImage.java:168)
at createtrainingsetfromimage.CreateTrainingSetFromImage.main(CreateTrainingSetFromImage.java:46)

1 ответ

Есть известная ошибка / ограничение в getDestination метод ImageReader базовый класс (супер класс из JPEGImageReader и все другие реализации считывателя ImageIO), который вычисляет ширину * высоту входного изображения, а не область, которую вы на самом деле пытаетесь прочитать... Это предотвращает чтение даже небольших частей таких изображений.

Код выглядит так, а width а также height Параметры - это размеры входа:

if ((long) width * height > Integer.MAX_VALUE) {
    throw new IllegalArgumentException("width*height > Integer.MAX_VALUE!");
}

В большинстве моих (библиотека TwelveMonkeys ImageIO) ImageReaders я обхожу это ограничение, используя другую реализацию getDestination метод. Но для JPEGImageReader Я делегирую фактическое декодирование com.sun....JPEGImageReader, который использует оригинальный метод и вызывает это исключение.

Возможно, можно обойти проблему, используя readRaster метод вместо read (так как он не использует getDestination метод), но это требует дополнительной работы, и у меня еще не было возможности проверить это.

Другие вопросы по тегам