Why is the quality of JPEG images produced by PIL so poor?

Question:

The JPEG images created with PIL (1.1.7) have very poor quality. Here is an example:

Input: https://s23.postimg.cc/8bks3x5p7/cover_1.jpg

Output: https://s23.postimg.cc/68ey9zva3/cover_2.jpg

The output image was created with the following code:

from PIL import Image
im = Image.open('/path/to/cover_1.jpg')
im.save('/path/to/cover_2.jpg', format='JPEG', quality=100)

The red text looks really awful. Saving the image with GIMP or Photoshop does not even come close to the bad quality created by PIL.
Does somebody know why this happens and how it can be solved?

Asked By: Pascal

||

Answers:

There are two parts to JPEG quality. The first is the quality setting which you have already set to the highest possible value.

JPEG also uses chroma subsampling, assuming that color hue changes are less important than lightness changes and some information can be safely thrown away. Unfortunately in demanding applications this isn’t always true, and you can most easily notice this on red edges. PIL doesn’t expose a documented setting to control this aspect.

Edit by Pascal Beyeler:

I just found an option which disables subsampling. You can set subsampling=0 when saving an image and the image looks way sharper! Thanks for your Help Mark!

im.save('/path/to/cover-2.jpg', format='JPEG', subsampling=0, quality=100)

Edit once more:

The subsampling option is finally documented, but I don’t know how long that’s been the case. Looks like you have the option of either an integer argument or a string; I still recommend 0 as shown above.

https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#jpeg

Note also that the documentation claims quality=95 is the best quality setting and that anything over 95 should be avoided. This may be a change from earlier versions of PIL.

Answered By: Mark Ransom
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.