[Image-SIG] PIL DPI trouble - Solved

Gary Bloom bloominator at hotmail.com
Mon Oct 8 22:23:48 CEST 2007

Hi Luca,

Sorry it has taken me so long to get back to you...

The first thing that jumps out at me about what you've written below is that 
you've been working on MacOSX and I have been working under XP.  I have done 
testing in the past few months, similar to what you've done, but without the 
same results. What you've done and the results you see make sense, but I 
just don't get the same thing under XP.  I have been running Python 2.4.4 
and PIL 1.1.6 under XP SP2.  My goal is to try to get my hands on an old Mac 
and redo my testing under OSX.  I am hoping that I will see your results, 
and then I can say that the problem is platform-specific.  As soon as I can 
get my hands on Photoshop or PSP for the Mac, I will try to make that 
happen.  By the way, is there any chance that you've done any testing under 



----- Original Message ----- 
From: "Luca De Santis" <lucadex at gmail.com>
To: "Gary Bloom" <bloominator at hotmail.com>; <Image-SIG at python.org>
Cc: <gbloom at sefas.com>
Sent: Wednesday, September 26, 2007 10:30 AM
Subject: Re: PIL DPI trouble - Solved

>> ....
>> Any thoughts on this?  Or perhaps can you
>> point me to someone who can shed even more light on the matter?
> Hi Gary
> sorry if it took me some time to get back on this topic.
> I made a couple of tests, that I describe below, which seems to
> confirm the correct behavior of PIL in managing the dpi of JPEGs. Take
> everything "with a grain of salt" since I'm not an expert on the
> subject: I just followed an empiric method which seems quite sound.
> First of all, I'm dealing with JPEGs so I can't say if what I'm doing
> applies to other file formats.
> My test environment consists of Python 2.1.3 (I used also Python 2.5
> with no apparent changes), PIL 1.1.6 on a Mac OS X 10.4. I'm reading
> images with Photoshop 7 plus Preview and Graphic Converter 5.9.5 which
> are Mac specific applications.
> # First test: reading a JPEG  image #
> I started from a simple JPEG created from Photoshop and saved at 150
> dpi (image.jpg).
> Hexdumping the image I get, as expected, the following values for the
> field of the JFIF Segment (cfr.
> http://en.wikipedia.org/wiki/JFIF#JFIF_Segment_Format ):
>   * Density Unit: 0x01 (dpi)
>   * X/Y Density: 0x0096 (150)
> I read the image with PIL in the following way:
>>>> import Image
>>>> i = Image.open('image.jpg')
>>>> i.info['dpi']
> (150, 150)
> Opening the image with the other two applications just gives the same
> value for the resolution.
> Now I opened again the image from Photoshop and saved it with the
> "Save for Web" option, using the name "image2.jpg".
> Hexdumping the image I had the following values for the JFIF attributes:
>   * Density Unit: 0x00 (No units, aspect ratio only specified)
>   * X/Y Density: 0x0064 (100)
> The 100 value seems to make sense because, according to the Density
> Unit value, it is the ratio (100%) by which you should use/visualize
> the image.
> Now with PIL you (correctly) can't read the dpi attribute anymore.
>>>> i = Image.open('image2.jpg')
>>>> i.info
> {'adobe_transform': 100, 'jfif_density': (100, 100), 'jfif_version':
> (1, 2), 'adobe': 100, 'jfif_unit': 0, 'jfif': 258}
> Opening the image again with Photoshop and selecting the "Image size"
> option you get 72 dpi but this seems a sort of default behavior of
> this application.
> Preview for example lefts blank in this case the dpi attribute, while
> Graphic Converter must have a bug since it thinks that the resolution
> is 100 dpi!
> _Conclusion_:
> PIL seems to interpret correctly the JFIF attributes. PIL also reads
> the EXIF attributes if present: they are stored in the 'app'
> dictionary associated to the Image instance.
> # Second test: saving a JPEG  image #
> Things are a bit different when the JPEG image is saved through PIL,
> which _by default_ doesn't handle the dpi attribute (see also below).
> In fact, I opened again the 150 dpi image, and saved with name
> "image3.jpg" through PIL with the following commands:
>>>> i = Image.open('image.jpg')
>>>> i.info['dpi']
> (150, 150)
>>>> i.save('image3.jpg')
>>>> i3 = Image.open('image3.jpg')
>>>> i3.info
> {'jfif_density': (1, 1), 'jfif_unit': 0, 'jfif': 257, 'jfif_version': (1, 
> 1)}
> Hexdumping image3.jpg you get:
>   * Density Unit: 0x00 (No units, aspect ratio only specified)
>   * X/Y Density: 0x0001
> Now, I don't really know if the correct value here should be 1 or 100
> (I honestly assume 100, so probably this could be a PIL bug).
> If you want to maintain the original dpi with PIL when saving the
> image just do the following:
>    i.save(filename, dpi=i.info['dpi'])
> In fact:
>>>> i = Image.open('image.jpg')
>>>> i.info['dpi']
> (150, 150)
>>>> i.save('image4.jpg', dpi=i.info['dpi'])
>>>> i4 = Image.open('image4.jpg')
>>>> i4.info
> {'dpi': (150, 150), 'jfif_density': (150, 150), 'jfif_unit': 1,
> 'jfif': 257, 'jfif_version': (1, 1)}
> Hexdumping this new image I got:
>   * Density Unit: 0x01 (dpi)
>   * X/Y Density: 0x0096 (150)
> and all the applications, Photoshop included, recognize the right
> resolution (150dpi) for the image.
> _Conclusion_:
> Just remember to specify the 'dpi' parameter when saving a JPEG whose
> resolution should be different than 72dpi.
> Sorry if I wrote too much! I honestly don't know other things on that
> so I hoped I helped to shed some light on this matter.
> Ciao,
> Luca
> Luca De Santis,
> Pisa, Italy

More information about the Image-SIG mailing list