Skip to content

Commit

Permalink
Merge pull request #2449 from hugovk/dpi-from-exif
Browse files Browse the repository at this point in the history
If DPI isn't in JPEG header, fetch from EXIF
  • Loading branch information
wiredfool committed Mar 29, 2017
2 parents 6ee13c6 + 07a9620 commit 977f319
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
5 changes: 5 additions & 0 deletions PIL/JpegImagePlugin.py
Expand Up @@ -117,6 +117,11 @@ def APP(self, marker):
# plus constant header size
self.info["mpoffset"] = self.fp.tell() - n + 4

# If DPI isn't in JPEG header, fetch from EXIF
if "dpi" not in self.info and "exif" in self.info:
x_resolution = self._getexif()[0x011A]
self.info["dpi"] = x_resolution[0] / x_resolution[1]


def COM(self, marker):
#
Expand Down
Binary file added Tests/images/photoshop-200dpi.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 10 additions & 2 deletions Tests/test_file_jpeg.py
Expand Up @@ -167,14 +167,14 @@ def test_progressive_large_buffer(self):

def test_progressive_large_buffer_highest_quality(self):
f = self.tempfile('temp.jpg')
im = self.gen_random_image((255,255))
im = self.gen_random_image((255, 255))
# this requires more bytes than pixels in the image
im.save(f, format="JPEG", progressive=True, quality=100)

def test_progressive_cmyk_buffer(self):
# Issue 2272, quality 90 cmyk image is tripping the large buffer bug.
f = BytesIO()
im = self.gen_random_image((256,256), 'CMYK')
im = self.gen_random_image((256, 256), 'CMYK')
im.save(f, format='JPEG', progressive=True, quality=94)

def test_large_exif(self):
Expand Down Expand Up @@ -500,6 +500,14 @@ def test_save_tiff_with_dpi(self):
reloaded.load()
self.assertEqual(im.info['dpi'], reloaded.info['dpi'])

def test_dpi_from_exif(self):
# Arrange
# This Photoshop CC 2017 image has DPI in EXIF not metadata
im = Image.open("Tests/images/photoshop-200dpi.jpg")

# Act / Assert
self.assertEqual(im.info.get("dpi"), 200)


if __name__ == '__main__':
unittest.main()

4 comments on commit 977f319

@jbarlow83
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wiredfool This is incorrect. DPI should be a tuple of (xres, yres), as it is everywhere else in Pillow.

@hugovk
Copy link
Member

@hugovk hugovk commented on 977f319 Apr 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed in code and docs:

The open() method may set the following info properties if available:
...
dpi
A tuple representing the reported pixel density in pixels per inch, if the file is a jfif file and the units are in inches.
...
The save() method supports the following options:
...
dpi
A tuple of integers representing the pixel density, (x,y).

I'll make a new PR.

@hugovk
Copy link
Member

@hugovk hugovk commented on 977f319 Apr 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbarlow83 Please could you have a look at PR #2472?

@hugovk
Copy link
Member

@hugovk hugovk commented on 977f319 Apr 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbarlow83 PR #2472 is merged.

Please sign in to comment.