Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIL does not recognize dpi of some jpeg images #8632

Closed
dziket opened this issue Dec 28, 2024 · 2 comments · Fixed by #8633
Closed

PIL does not recognize dpi of some jpeg images #8632

dziket opened this issue Dec 28, 2024 · 2 comments · Fixed by #8633
Labels

Comments

@dziket
Copy link

dziket commented Dec 28, 2024

It seems that for some jpeg images Pillow does not report correct DPI.

For instance, I created with Gimp a PNG file of size 1x1 pixels with resolution of 123 dpi (test2.png) and then I converted it with imagemagick to test2.jpg. The command was:

$ convert --version
Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib
$ convert test2.png test2.jpg 

I attach both files (zipped, as images.zip). When I use Pillow to read dpi of test2.jpg, this is what I get:

$ ipython3 

In [1]: from PIL import Image                                                                                                                                 

In [2]: print(Image.__version__)                                                                                                                              
10.4.0

In [3]: Image.open('test2.jpg').info                                                                                                                          
Out[3]: {'jfif': 257, 'jfif_version': (1, 1), 'jfif_unit': 2, 'jfif_density': (48, 48)}

I see that jfif_density and jfif_unit pair is correct (48 px/cm is 123 px/in), but I think that this info structure should also contain 'dpi' entry - and it does not contain it. For instance, when I create a similar jpeg file directly from Gimp (test3.jpg, also attached), it works as I want:

$ ipython3 
/usr/lib/python3/dist-packages/IPython/core/interactiveshell.py:935: UserWarning: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
  warn("Attempting to work in a virtualenv. If you encounter problems, please "
Python 3.8.10 (default, Nov  7 2024, 13:10:47) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from PIL import Image                                                                                                                                 

In [2]: print(Image.__version__)                                                                                                                              
10.4.0

In [3]: Image.open('test3.jpg').info                                                                                                                          
Out[3]: 
{'jfif': 257,
 'jfif_version': (1, 1),
 'dpi': (123, 123),
 'jfif_unit': 1,
 'jfif_density': (123, 123),
 'exif': b'Exif\x00\x00II*\x00\x08\x00\x00\x00\x07\x00\x0e\x01\x02\x00\x12\x00\x00\x00b\x00\x00\x00\x1a\x01\x05\x00\x01\x00\x00\x00t\x00\x00\x00\x1b\x01\x05\x00\x01\x00\x00\x00|\x00\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x001\x01\x02\x00\r\x00\x00\x00\x84\x00\x00\x002\x01\x02\x00\x14\x00\x00\x00\x92\x00\x00\x00i\x87\x04\x00\x01\x00\x00\x00\xa6\x00\x00\x00\x00\x00\x00\x00Created with GIMP\x00{\x00\x00\x00\x01\x00\x00\x00{\x00\x00\x00\x01\x00\x00\x00GIMP 2.10.18\x00\x002024:12:28 07:13:34\x00\x02\x00\x86\x92\x07\x00\x19\x00\x00\x00\xc4\x00\x00\x00\x01\xa0\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Created with GIMP\x00',
 'progressive': 1,
 'progression': 1}
@radarhere
Copy link
Member

Looking at the code, Pillow does use the JFIF density to set info["dpi"] - if the JFIF unit is 1, meaning that the JFIF density is per inch.

if jfif_unit == 1:
self.info["dpi"] = jfif_density
self.info["jfif_unit"] = jfif_unit
self.info["jfif_density"] = jfif_density

So your request is that when the JFIF unit is 2, meaning that the JFIF density is per cm, then info["dpi"] should be inferred from that? That seems reasonable. I've created #8633

@dziket
Copy link
Author

dziket commented Dec 28, 2024

Yes, you summarized the problem better than me - the problem is "what should be the value of DPI if JFIF unit is 2".
The whole thing have started when I noticed today that img2pdf (which uses Pillow) do not support correctly files in which JFIF unit is 2 (see: josch/img2pdf#40 ). So now some code needs to support this scenario - either img2pdf or Pillow itself. And probably it's better if Pillow takes care of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants