Преобразование PNG в JPEG
У меня возникают проблемы с преобразованием простого 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-полосные байтовые данные. на com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148)...
Из вариантов. Любое предложение?
Ответы
Ответ 1
у вас, вероятно, есть альфа-канал в 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);
Ответ 2
Возможно, было бы проще использовать ImageIO
, чтобы прочитать PNG в BufferedImage
и записать изображение в формате JPEG.
Приложение: при таком подходе преобразование обрабатывается прозрачно писателем ImageTranscoder
.
BufferedImage img = ImageIO.read(new File("image.png"));
ImageIO.write(img, "jpg", new File("image.jpg"));
Ответ 3
Я также обнаружил, что чтение PNG-изображения в BufferedImage с ImageIO (Java 6) и запись его в название формата JPG исказили изображение. Изображение было там, но цвета выглядели "соляризованными" и почти перевернутыми. Файл JPG был намного меньше, чем PNG файл, поэтому было сделано много сжатия. Я не вижу, как вы можете контролировать сжатие или глубину цвета.
Ответ 4
Я полагаю, что JAI читает изображение PNG с индексированной цветовой моделью и может записывать только 8-битные оттенки серого или 24-битные цветные изображения в виде файлов JPEG.
Если вам не требуется использовать JAI для этой задачи, вы можете использовать ImageIO вместо:
ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg"));
Ответ 5
Я получил следующее сообщение в немного другом контексте. Избавление от альфа-канала решает проблему
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)