Reputation: 195
I'm having problems converting a simple PNG into a JPEG format. I'm using the following code:
...
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;
}
...
I end up with an JAI exception -> java.lang.RuntimeException: Only 1, or 3-band byte data may be written. at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148) ...
Ran out of options. Any suggestion?
Upvotes: 18
Views: 32052
Reputation: 81
I had corrupted file after conversion with other solutions but this method worked for me:
public static void formatConverter(String pngFile, String jpgFile) {
try {
File input = new File(pngFile);
File output = new File(jpgFile);
BufferedImage image = ImageIO.read(input);
BufferedImage result = new BufferedImage(
image.getWidth(),
image.getHeight(),
BufferedImage.TYPE_INT_RGB);
result.createGraphics().drawImage(image, 0, 0, Color.WHITE, null);
ImageIO.write(result, "jpg", output);
} catch (IOException e) {
e.printStackTrace();
}
}
Upvotes: 6
Reputation: 71
see Converting transparent gif / png to jpeg using java
Have a look at the solution that redraws with the graphics environment posted by harmanjd. The solution with the DirectColorModel doesn't compile and should be wiped away. I don't have enough rep points to comment directly there.
Upvotes: 2
Reputation: 91
I was getting the following message in a slightly different context. Getting rid of the alpha channel solved the problem
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)
Upvotes: 2
Reputation: 179
I also found that reading a PNG image into a BufferedImage with ImageIO (Java 6) and writing it out to a JPG "format name" corrupted the image. The image was there, but the colors looked "solarized" and almost inverted. The JPG file was much smaller than the PNG file for sure, so a lot of compression was done. I don't see how you might control the compression or color depth.
Upvotes: 7
Reputation: 205765
It might be easier to use ImageIO
to read the PNG into a BufferedImage
and write the image out in JPEG format.
Addendum: In this approach, the conversion is handled transparently by the writer's ImageTranscoder
.
BufferedImage img = ImageIO.read(new File("image.png"));
ImageIO.write(img, "jpg", new File("image.jpg"));
Upvotes: 30
Reputation: 1764
you probably have alpha channel in the png that you need to get rid of before trying to write the jpg.
Create a new BufferedImage with type TYPE_INT_RGB (not TYPE_INT_ARGB), and then write your source image (pngImage) onto the new blank image.
Something like this (warning, not tested code):
BufferedImage newImage = new BufferedImage( pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newImage.createGraphics().drawImage( pngImage, 0, 0, Color.BLACK, null);
Upvotes: 25
Reputation: 34313
I suppse that JAI reads the PNG image with an indexed colour model and is only able to write 8-bit grayscale or 24-bit colour images as JPEG files.
If you are not required to use JAI for this task, you should be able to use ImageIO instead:
ImageIO.write(ImageIO.read(new File("in.png")), "JPEG", new File("out.jpg"));
Upvotes: 5