Skip to content

Commit a72ae68

Browse files
authored
Merge pull request #5476 from radarhere/dpi_rounding
2 parents d53a664 + 18e204d commit a72ae68

File tree

8 files changed

+18
-52
lines changed

8 files changed

+18
-52
lines changed

Tests/images/hopper_roundDown.bmp

-48.1 KB
Binary file not shown.

Tests/images/iptc_roundDown.jpg

-20.5 KB
Binary file not shown.

Tests/test_file_bmp.py

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,46 +63,33 @@ def test_dpi():
6363

6464
output.seek(0)
6565
with Image.open(output) as reloaded:
66-
assert reloaded.info["dpi"] == dpi
66+
assert reloaded.info["dpi"] == (72.008961115161, 72.008961115161)
6767

6868

6969
def test_save_bmp_with_dpi(tmp_path):
7070
# Test for #1301
7171
# Arrange
7272
outfile = str(tmp_path / "temp.jpg")
7373
with Image.open("Tests/images/hopper.bmp") as im:
74+
assert im.info["dpi"] == (95.98654816726399, 95.98654816726399)
7475

7576
# Act
7677
im.save(outfile, "JPEG", dpi=im.info["dpi"])
7778

7879
# Assert
7980
with Image.open(outfile) as reloaded:
8081
reloaded.load()
81-
assert im.info["dpi"] == reloaded.info["dpi"]
82-
assert im.size == reloaded.size
82+
assert reloaded.info["dpi"] == (96, 96)
83+
assert reloaded.size == im.size
8384
assert reloaded.format == "JPEG"
8485

8586

86-
def test_load_dpi_rounding():
87-
# Round up
88-
with Image.open("Tests/images/hopper.bmp") as im:
89-
assert im.info["dpi"] == (96, 96)
90-
91-
# Round down
92-
with Image.open("Tests/images/hopper_roundDown.bmp") as im:
93-
assert im.info["dpi"] == (72, 72)
94-
95-
96-
def test_save_dpi_rounding(tmp_path):
87+
def test_save_float_dpi(tmp_path):
9788
outfile = str(tmp_path / "temp.bmp")
9889
with Image.open("Tests/images/hopper.bmp") as im:
99-
im.save(outfile, dpi=(72.2, 72.2))
90+
im.save(outfile, dpi=(72.21216100543306, 72.21216100543306))
10091
with Image.open(outfile) as reloaded:
101-
assert reloaded.info["dpi"] == (72, 72)
102-
103-
im.save(outfile, dpi=(72.8, 72.8))
104-
with Image.open(outfile) as reloaded:
105-
assert reloaded.info["dpi"] == (73, 73)
92+
assert reloaded.info["dpi"] == (72.21216100543306, 72.21216100543306)
10693

10794

10895
def test_load_dib():

Tests/test_file_jpeg.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -656,15 +656,6 @@ def test_save_tiff_with_dpi(self, tmp_path):
656656
reloaded.load()
657657
assert im.info["dpi"] == reloaded.info["dpi"]
658658

659-
def test_load_dpi_rounding(self):
660-
# Round up
661-
with Image.open("Tests/images/iptc_roundUp.jpg") as im:
662-
assert im.info["dpi"] == (44, 44)
663-
664-
# Round down
665-
with Image.open("Tests/images/iptc_roundDown.jpg") as im:
666-
assert im.info["dpi"] == (2, 2)
667-
668659
def test_save_dpi_rounding(self, tmp_path):
669660
outfile = str(tmp_path / "temp.jpg")
670661
with Image.open("Tests/images/hopper.jpg") as im:

Tests/test_file_png.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -386,25 +386,12 @@ def test_roundtrip_dpi(self):
386386
# Check dpi roundtripping
387387

388388
with Image.open(TEST_PNG_FILE) as im:
389-
im = roundtrip(im, dpi=(100, 100))
390-
assert im.info["dpi"] == (100, 100)
389+
im = roundtrip(im, dpi=(100.33, 100.33))
390+
assert im.info["dpi"] == (100.33, 100.33)
391391

392-
def test_load_dpi_rounding(self):
393-
# Round up
392+
def test_load_float_dpi(self):
394393
with Image.open(TEST_PNG_FILE) as im:
395-
assert im.info["dpi"] == (96, 96)
396-
397-
# Round down
398-
with Image.open("Tests/images/icc_profile_none.png") as im:
399-
assert im.info["dpi"] == (72, 72)
400-
401-
def test_save_dpi_rounding(self):
402-
with Image.open(TEST_PNG_FILE) as im:
403-
im = roundtrip(im, dpi=(72.2, 72.2))
404-
assert im.info["dpi"] == (72, 72)
405-
406-
im = roundtrip(im, dpi=(72.8, 72.8))
407-
assert im.info["dpi"] == (73, 73)
394+
assert im.info["dpi"] == (95.9866, 95.9866)
408395

409396
def test_roundtrip_text(self):
410397
# Check text roundtripping

src/PIL/BmpImagePlugin.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,7 @@ def _bitmap(self, header=0, offset=0):
115115
)
116116
file_info["colors"] = i32(header_data, 28)
117117
file_info["palette_padding"] = 4
118-
self.info["dpi"] = tuple(
119-
int(x / 39.3701 + 0.5) for x in file_info["pixels_per_meter"]
120-
)
118+
self.info["dpi"] = tuple(x / 39.3701 for x in file_info["pixels_per_meter"])
121119
if file_info["compression"] == self.BITFIELDS:
122120
if len(header_data) >= 52:
123121
for idx, mask in enumerate(

src/PIL/JpegImagePlugin.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#
3434
import array
3535
import io
36+
import math
3637
import os
3738
import struct
3839
import subprocess
@@ -162,15 +163,17 @@ def APP(self, marker):
162163
dpi = float(x_resolution[0]) / x_resolution[1]
163164
except TypeError:
164165
dpi = x_resolution
166+
if math.isnan(dpi):
167+
raise ValueError
165168
if resolution_unit == 3: # cm
166169
# 1 dpcm = 2.54 dpi
167170
dpi *= 2.54
168-
self.info["dpi"] = int(dpi + 0.5), int(dpi + 0.5)
171+
self.info["dpi"] = dpi, dpi
169172
except (KeyError, SyntaxError, ValueError, ZeroDivisionError):
170173
# SyntaxError for invalid/unreadable EXIF
171174
# KeyError for dpi not included
172175
# ZeroDivisionError for invalid dpi rational value
173-
# ValueError for x_resolution[0] being an invalid float
176+
# ValueError for dpi being an invalid float
174177
self.info["dpi"] = 72, 72
175178

176179

src/PIL/PngImagePlugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ def chunk_pHYs(self, pos, length):
500500
px, py = i32(s, 0), i32(s, 4)
501501
unit = s[8]
502502
if unit == 1: # meter
503-
dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
503+
dpi = px * 0.0254, py * 0.0254
504504
self.im_info["dpi"] = dpi
505505
elif unit == 0:
506506
self.im_info["aspect"] = px, py

0 commit comments

Comments
 (0)