Преобразование PNG в JPEG - PullRequest
       43

Преобразование PNG в JPEG

13 голосов
/ 18 февраля 2010

У меня проблемы с преобразованием простого PNG в формат JPEG.Я использую следующий код:

...

    File png = new File(filePath);
    try {
        SeekableStream s = new FileSeekableStream(png);
        PNGDecodeParam pngParams = new PNGDecodeParam();
        ImageDecoder dec = ImageCodec.createImageDecoder("png", s, pngParams);
        RenderedImage pngImage = dec.decodeAsRenderedImage();
        JPEGEncodeParam jparam = new JPEGEncodeParam();
        jparam.setQuality(0.50f); // e.g. 0.25f
        File jpeg = new File("jpeg.jpeg");
        FileOutputStream out = new FileOutputStream(jpeg);

        ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", out, jparam); 

        encoder.encode(pngImage);

        s.close();

    } catch (IOException e) {
        ok = false;
        e.printStackTrace();
    }

    return ok;
}

...

Я получаю исключение JAI -> java.lang.RuntimeException:Только 1 или 3-полосные байтовые данные могут быть записаны.at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode (JPEGImageEncoder.java:148) ...

Закончились варианты.Любое предложение?

Ответы [ 5 ]

24 голосов
/ 18 февраля 2010

Может быть проще использовать ImageIO для считывания PNG в BufferedImage и записи изображения в формате JPEG.

Добавление: в этом подходе преобразование прозрачно обрабатывается автором ImageTranscoder.

BufferedImage img = ImageIO.read(new File("image.png"));
ImageIO.write(img, "jpg", new File("image.jpg"));
19 голосов
/ 18 февраля 2010

у вас, вероятно, есть альфа-канал в png, от которого вам нужно избавиться, прежде чем пытаться написать jpg.

Создайте новый BufferedImage с типом TYPE_INT_RGB (не TYPE_INT_ARGB), а затем запишите исходное изображение (pngImage) на новое пустое изображение.

Примерно так (предупреждение, не проверенный код):

BufferedImage newImage = new BufferedImage( pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newImage.createGraphics().drawImage( pngImage, 0, 0, Color.BLACK, null);
4 голосов
/ 27 марта 2013

Я также обнаружил, что чтение изображения PNG в BufferedImage с ImageIO (Java 6) и запись его в JPG «имя формата» повредило изображение. Изображение было там, но цвета выглядели «соляризованными» и почти перевернутыми. Файл JPG был намного меньше, чем файл PNG, поэтому было сделано много сжатий. Я не понимаю, как вы можете контролировать сжатие или глубину цвета.

4 голосов
/ 18 февраля 2010

Я полагаю, что JAI читает изображение PNG с индексированной цветовой моделью и может записывать только 8-битные изображения в градациях серого или 24-битные цветные изображения в виде файлов JPEG.

Если вам не нужно использовать JAI для этой задачи, вы должны иметь возможность использовать ImageIO вместо:

ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg"));
1 голос
/ 27 октября 2015

Я получил следующее сообщение в несколько ином контексте.Избавление от альфа-канала решило проблему

javax.imageio.IIOException: Sample size must be <= 8
    at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:435)
    at javax.imageio.ImageWriter.write(ImageWriter.java:580)
    at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageWriter.write(Unknown Source)
    at net.sf.basedb.util.ImageTools.tiffToJpg(ImageTools.java:98)
    at net.sf.basedb.util.ImageTools.main(ImageTools.java:118)
...