I've converted PNG to JPEG with both java and python PIL. Python code :
from PIL import Image
img = Image.open('input.png')
img.save('output.jpg', 'JPEG', quality=100)
For converting the Java code I used:
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
public class PngToJpeg {
public static void main(String[] args) {
// Specify the input and output file paths
String inputFile = "./test.png";
String outputFile = "./testout.jpg";
// Read the input image into a BufferedImage
BufferedImage inputImage = null;
try {
inputImage = ImageIO.read(new File(inputFile));
} catch (IOException e) {
e.printStackTrace();
}
// Write the input image to the output file as a JPEG image
try {
ImageIO.write(inputImage, "jpg", new File(outputFile));
} catch (IOException e) {
e.printStackTrace();
}
}
}
below code shows me the exact value of each pixel:
from PIL import Image
img = Image.open("test.jpeg")
pixellist = list(img.getdata())
print(pixellist)
When I convert JPEG to PNG with both Python and JAVA the pixel values are exactly the same. But when its the other way around it seems like there were 2 or 3 subtracted from many pixels. For example:
JPEG pixels(after conversion):
(22, 22, 22), (219, 219, 219), (219, 219, 219), (219, 219, 219), (219, 219, 219)
PNG pixels(original image):
(22, 22, 22), (222, 222, 222), (222, 222, 222), (222, 222, 222), (222, 222, 222)
Things to note here that the PNG has no ALPHA channel.
So what am i missing here? How to achieve the exact same pixel values when converting a PNG to JPEG?
I have also checked imagemagick, convert. They appear to be the same result.
In short, JPEG is a lossy compression format at all quality levels. It doesn't matter if you set the quality to 100%. See this earlier question "Is JPEG lossless when quality is set to 100?". There are extensions such as JPEG-LS that are lossless, but it is a totally different compression algorithm with its own file extension (.jls) and container, and most mainstream software cannot decode it. If you need lossless, here are some options:
lossless=True
to save()
.This article does a basic comparison of them, and this reddit post does a more thorough comparison. Overall, I'd say that WebP offers the best balance of wide software support and high compression ratios.