Why have JPG images such a poor quality?

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
mst1978
Posts: 8
Joined: Wed Jul 19, 2006 3:35 pm

Why have JPG images such a poor quality?

Post by mst1978 » Wed Jul 19, 2006 3:52 pm

I know that I can use PNG instead of JPG but I woner why a JPG has such a poor quality, even if I choose the max. quality setting.

Will this be fixed in future?
A JPG is smaller and when creating big (or many) charts it is important to take care about the size of the files.

Taqua
JFreeReport Project Leader
Posts: 698
Joined: Fri Mar 14, 2003 3:34 pm
Contact:

Post by Taqua » Wed Jul 19, 2006 4:22 pm

Hi,

the poor quality of JPEGs is caused by the discrete cosinus transformation that is used to reduce non-significant information from the image data.

That transformation works best, if the data does not have high fequencies. Sadly, an sharp edge from white to black (or vice versa) is a high frequency transition so JPEG fails misserably there.

It is rather common knowledge, that JPEG is good for photos, but not for text or charts. PNG, in contrast, uses a loseless compression algorithm, and is therefore much better suited for charts or text.

http://www.prepressure.com/techno/compressionjpeg.htm
http://www.faqs.org/faqs/compression-fa ... ion-6.html

As the poor quality is a mathematical artifact, there will be no fix possible.

Regards,
Thomas

mst1978
Posts: 8
Joined: Wed Jul 19, 2006 3:35 pm

Post by mst1978 » Thu Jul 20, 2006 8:36 am

Taqua wrote:Hi,

the poor quality of JPEGs is caused by the discrete cosinus transformation that is used to reduce non-significant information from the image data.

That transformation works best, if the data does not have high fequencies. Sadly, an sharp edge from white to black (or vice versa) is a high frequency transition so JPEG fails misserably there.

It is rather common knowledge, that JPEG is good for photos, but not for text or charts. PNG, in contrast, uses a loseless compression algorithm, and is therefore much better suited for charts or text.

http://www.prepressure.com/techno/compressionjpeg.htm
http://www.faqs.org/faqs/compression-fa ... ion-6.html

As the poor quality is a mathematical artifact, there will be no fix possible.

Regards,
Thomas

Thanks for the explanation.

But it should be possible to make high quality JPGs... even with high fequencies in the image.

Just 1 minute ago I draw a similar chart with Paint .NET and saved it as a JPG (max. quality). The edges are pure. There are only very small errors which you can see only at a very high zoom.

Paint .NET is (I think) Open Source.
Perhaps you may use their JPG algorithms?
Please take a look here:
http://www.eecs.wsu.edu/paint.net/

Bye,

Miroslav Stimac

P.S.:
Thanks for JFreeChart.
It's really a great API. :)

Taqua
JFreeReport Project Leader
Posts: 698
Joined: Fri Mar 14, 2003 3:34 pm
Contact:

Post by Taqua » Thu Jul 20, 2006 9:29 am

Hi,

the JPEG-Algorithm is a well-defined piece of mathematics. Assuming that the same input parameters get used for the encoding, the Encoders will not yield different results, no matter whether it is implemented in C, Java or any other language. For that purpose, even a human could encode that stuff manually, only armed with pen and paper, and those results would not be different.

So my assumption is, that you do not use the same quality parameters. The default in JFreeChart is 0.75, but it is possible to set a different quality.

The JPEG implementation in Java uses libjpeg, and chances are high that .NET uses exactly the same code (as libjpeg is opensource, and MS (despite some political quirks) is an as happy opensource user as everyone else.

To compare the encoding results, make sure that you use exactly the same input, and use exactly the same parameters. Everything else would be funny, but unscientific and a complete waste of time.

Save the same chart as PNG and JPEG (make sure that you either specify the quality here *or* that you use 0.75 for the .NET run), and then load the PNG in that paint programm and save it as JPEG (with exactly the same parameters!). You will not notice a difference. (In the ideal case, both results will be binary identical.)

Regards,
Thomas

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Post by david.gilbert » Thu Jul 20, 2006 10:14 am

I'm looking through the JFreeChart code that writes the JPEGs, and I can't see where the quality setting is actually used. So I think you might have found a bug. I'll keep investigating and report back soon...
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Post by david.gilbert » Thu Jul 20, 2006 11:34 am

OK, the quality parameter is being ignored, and to be fair to the developer that wrote this code it does say that in the API docs.

I've modified the encode() method in the SunJPEGEncoderAdapter class to read as follows:

Code: Select all

    public void encode(BufferedImage bufferedImage, OutputStream outputStream) 
            throws IOException {
        if (bufferedImage == null) {
            throw new IllegalArgumentException("Null 'image' argument.");
        }
        if (outputStream == null) {
            throw new IllegalArgumentException("Null 'outputStream' argument.");
        }
        Iterator iterator = ImageIO.getImageWritersByFormatName("jpeg");
        ImageWriter writer = (ImageWriter) iterator.next();
        ImageWriteParam p = writer.getDefaultWriteParam();
        p.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        p.setCompressionQuality(this.quality);
        ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
        writer.setOutput(ios);
        writer.write(null, new IIOImage(bufferedImage, null, null), p);
        ios.flush();
        writer.dispose();
        ios.close();
    }
A quality setting of 0.95f looks pretty reasonable (certainly better than the default of 0.75f). Even so, I still recommend using PNG format for charts in preference to JPEG.

I'll commit the above change to CVS as soon as SourceForge allows.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

mst1978
Posts: 8
Joined: Wed Jul 19, 2006 3:35 pm

Post by mst1978 » Thu Jul 20, 2006 11:36 am

Yes, there could be a bug.

I done as you told me:
Even if I use only a quality setting of 75% and convert a PNG (created by JFreeChart) to a JPG with Paint .NET it looks MUCH better than the same chart saved as a JPG with JFreeChart.

Also I notices that the changing of the quality settings in JFreeChart have no (at least none visible) effects on the quality of the JPG image.

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Post by david.gilbert » Thu Jul 20, 2006 3:32 pm

See my previous post (I think we both posted at around the same time so you might have missed it). Anyway, I've committed the fix to CVS now, ready for the 1.0.2 release.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

mst1978
Posts: 8
Joined: Wed Jul 19, 2006 3:35 pm

Post by mst1978 » Fri Jul 21, 2006 8:43 am

Thanks :)

Locked