Есть ли 100% Java -альтернатива Imageio для чтения файлов JPEG?

StackOverflow https://stackoverflow.com/questions/2999528

Вопрос

Мы используем Java2D для изменения размера фотографий, загруженных на наш веб -сайт, но мы сталкиваемся с проблемой (кажущаяся старая, Cf.: http://forums.sun.com/thread.jspa?threadid=5425569) - Несколько конкретных JPEG поднимают CMMException Когда мы пытаемся ImageIO.read() Входная сеть, содержащая их двоичные данные:

java.awt.color.CMMException: Invalid image format
 at sun.awt.color.CMM.checkStatus(CMM.java:131)
 at sun.awt.color.ICC_Transform.<init>(ICC_Transform.java:89)
 at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:516)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1114)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897)
 at javax.imageio.ImageIO.read(ImageIO.java:1422)
 at javax.imageio.ImageIO.read(ImageIO.java:1326)
    ...

(обрезал оставшуюся часть трассировки стека, которая является нашим ImageIO.read() Звоните, код сервлета и тому подобное)

Мы сузили его до фотографий, сделанных на определенных камерах, и я выбрал фотографию, которая запускает эту ошибку: http://img214.imageshack.us/img214/5121/estacaosp.jpg. Анкет Мы заметили, что это происходит только с Sun's JVM (на Linux и Mac, только что протестировал его на 1.6.0_20) - тестовая машина с OpenJDK читает одни и те же фотографии без сцепления, возможно, из -за другой реализации считывателя JPEG.

К сожалению, мы не можем переключить JVM в производстве или использовать такие собственные решения, как ImageMagick (ImageMagick ( http://www.imagemagick.org/ ).

Учитывая это, мой вопрос: существует ли замена для считывателя Imageios JPEG, который может обрабатывать такие фотографии, как связанный? Если нет, есть ли еще одно 100% чистого решения для изменения размера размера с чистым Java, которое мы можем использовать?

Благодарю вас!

Это было полезно?

Решение

Одной из возможной полезной библиотеки для вас может быть библиотека Advanced Imaging Java (Джай)

Использование этой библиотеки может быть немного сложнее, чем использование Imageio, но в быстром тесте я только что запустил, он открыл и отобразил связанный с вами файл изображения.

public static void main(String[] args) {
        RenderedImage image = JAI.create("fileload", "estacaosp.jpg");

        float scale=(float) 0.5;

        ParameterBlock pb = new ParameterBlock();
        pb.addSource(image);

        pb.add(scale);
        pb.add(scale);
        pb.add(1.0F);
        pb.add(1.0F);

        pb.add(new InterpolationNearest() );// ;InterpolationBilinear());
        image = JAI.create("scale", pb);

        // Create an instance of DisplayJAI.
        DisplayJAI srcdj = new DisplayJAI(image);

        JScrollPane srcScrollPaneImage = new JScrollPane(srcdj);

// Use a label to display the image
        JFrame frame = new JFrame();

        frame.getContentPane().add(srcScrollPaneImage, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

После запуска этого кода изображение, кажется, загружается нормально. Затем он изменяется на 50%, используя ParamaterBlock

И, наконец, если вы хотите сохранить файл, вы можете просто позвонить:

String filename2 = new String ("tofile.jpg");
  String format = new String ("JPEG");
  RenderedOp op = JAI.create ("filestore", image, filename2, format);

Я надеюсь, что это помогает вам. Удачи.

Другие советы

Старый пост, но для будущего ссылки:

Вдохновлен этим вопросом и ссылками, найденными здесь, я написал плагин jpegimagereader для Imageio, который поддерживает изображения JPEG с такими «плохими» цветными профилями ICC («проблема» - это намерение рендеринга в профиле ICC, несовместимо с ColorConvertop Java. ) Это простой ява и не требует Джая.

Исходный код и связанные бинарные сборки свободно доступны из Двенадцатый проект на GitHub.

Я столкнулся с той же проблемой. Я неохотно использовал Джай, так как он устарел, но похоже, что это самое короткое решение.

Этот код преобразует входной сериал в буферизацию, используя Sun's Imageio (Fast) или в тех немногих случаях, когда возникает эта проблема, используя Jai:

public static BufferedImage read(InputStream is) throws IOException {
    try {
        // We try it with ImageIO
        return ImageIO.read(ImageIO.createImageInputStream(is));
    } catch (CMMException ex) {
        // If we failed...
        // We reset the inputStream (start from the beginning)
        is.reset();
        // And use JAI
        return JAI.create("stream", SeekableStream.wrapInputStream(is, true)).getAsBufferedImage();
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top