How to convert PNG with alpha to JPEG conserving colors using JAVA
alpha, colors, java, jpeg, png
Solution
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?
Problem
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.