I'm having some trouble in converting a PNG with Alpha to JPEG from Wiki.
This is the image: http://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Radio_SRF_3.svg/500px-Radio_SRF_3.svg.png
Original:
The converted JPEG file has wrong colors. It's more grey than darker now.
This is how I do the conversion:
Remove alpha:
public static BufferedImage imageFillAlphaWithColor(BufferedImage image, Color fillColor) {
if (image.getColorModel().getTransparency() == Transparency.OPAQUE) return image;
int w = image.getWidth();
int h = image.getHeight();
BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, fillColor, null);
g.dispose();
return newImage;
}
Jpeg compression:
public static byte[] compressedJpegImage(BufferedImage image, float quality) {
byte jpegImage[] = null;
try {
// Find a jpeg writer
ImageWriter writer = null;
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");
if (iter.hasNext()) {
writer = (ImageWriter) iter.next();
}
// Prepare output
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
// Set the compression quality
ImageWriteParam iwparam = writer.getDefaultWriteParam();
iwparam.setProgressiveMode(ImageWriteParam.MODE_DEFAULT);
iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwparam.setCompressionQuality(quality);
// Write the image
writer.write(null, new IIOImage(image, null, null), iwparam);
// Cleanup
ios.flush();
writer.dispose();
ios.close();
jpegImage = os.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return jpegImage;
}
And store it to JPEG via ImageIO.
Any idea how to preserve the color space to keep the colors like they are in the original?
UPDATE
Issue was caused by ImageMagick when resized. Seems like ImageMagick did change the color space to TYPE_CUSTOM and Java is not able to handle that.
Current solution:
Remove alpha just before I start resizing the image via ImageMagick.
Still haven't found a solution to convert the color space from "CUSTOM" back to "ARGB". So this is just a "workaround" for this issue.
You aren't actually removing the alpha values. Java divides the color values by the alpha when you do what you did in the imageFillAlphaWithColor
method.
I recommend using the AlphaComposite
class to actually remove the alpha.
Here's the Oracle tutorial on how to Composite Graphics: http://docs.oracle.com/javase/tutorial/2d/advanced/compositing.html
Without being able to test easily, I think what you need to do is this:
Graphics2D g = newImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.drawImage(image, 0, 0, fillColor, null);
If that doesn't work, read this related question: Change the alpha value of a BufferedImage?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With