The rest of the code you skipped (saving ImageIO) and if the PNG you are reading has a transparent channel or not (as @Daft Punk pointed out) are important bits here.
I am ready to bet $ 1 for the fact that your PNG has an alpha channel, and JPG does not support alpha; unfortunately, the Java JPG encoder does not know to ignore the alpha channel on the BufferedImage that you are passing, and it will discard one of the REAL color channels (R / G / B) in favor of writing out alpha values instead of one of these color channels.
For example, if you have:
ARGB
The Java JPG encoder will output the following 3 channels, thinking they are RGB:
[ARG]
and drop the BLUE channel.
Fortunately, the fix is simple. Just create a new BufferedImage of type TYPE_INT_RGB as follows:
BufferedImage imageToSave = new BufferedImage(imagemJpg.getWidth(), imagemJpg.getHeight(), BufferedImage.TYPE_INT_RGB);
then you need to “render” the BufferedImage with the alpha channel to remove the alpha channel:
Graphics g = imageToSave.getGraphics(); g.drawImage(imagemJpg, 0, 0, null);
Now you can save the resulting imageToSave image as a JPG, and it will look normal.
TIP . Don’t forget that if you don’t like how the image looks (blurry, artifact, etc.), you need to pass the arguments directly to the Java JPG encoder to report it ( read this ). This is rarely a problem, but in the past it came about when people say: "imgscalr looks Bad!" - it turns out that BufferedImage is really nice and sharp, but the Java encoder compresses the result too aggressively.
I meant to pay attention to these slightly annoying results with Java images by adding some additional IO helpers to the imgscalr library so that you can simply upload and save files, rather than worry about these detailed details.