Skip to content

Commit

Permalink
Merge pull request #5446 from radarhere/tiff_dpi_rounding
Browse files Browse the repository at this point in the history
Removed TIFF DPI rounding
  • Loading branch information
radarhere committed May 9, 2021
2 parents b256541 + 43faa38 commit 9bbe53a
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 25 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file removed Tests/images/hopper_roundDown_2.tif
Binary file not shown.
Binary file removed Tests/images/hopper_roundDown_3.tif
Binary file not shown.
Binary file removed Tests/images/hopper_roundDown_None.tif
Binary file not shown.
37 changes: 17 additions & 20 deletions Tests/test_file_tiff.py
Expand Up @@ -137,29 +137,26 @@ def test_int_resolution(self):
im._setup()
assert im.info["dpi"] == (71.0, 71.0)

def test_load_dpi_rounding(self):
for resolutionUnit, dpi in ((None, (72, 73)), (2, (72, 73)), (3, (183, 185))):
with Image.open(
"Tests/images/hopper_roundDown_" + str(resolutionUnit) + ".tif"
) as im:
assert im.tag_v2.get(RESOLUTION_UNIT) == resolutionUnit
assert im.info["dpi"] == (dpi[0], dpi[0])

with Image.open(
"Tests/images/hopper_roundUp_" + str(resolutionUnit) + ".tif"
) as im:
assert im.tag_v2.get(RESOLUTION_UNIT) == resolutionUnit
assert im.info["dpi"] == (dpi[1], dpi[1])

def test_save_dpi_rounding(self, tmp_path):
@pytest.mark.parametrize(
"resolutionUnit, dpi",
[(None, 72.8), (2, 72.8), (3, 184.912)],
)
def test_load_float_dpi(self, resolutionUnit, dpi):
with Image.open(
"Tests/images/hopper_float_dpi_" + str(resolutionUnit) + ".tif"
) as im:
assert im.tag_v2.get(RESOLUTION_UNIT) == resolutionUnit
for reloaded_dpi in im.info["dpi"]:
assert float(reloaded_dpi) == dpi

def test_save_float_dpi(self, tmp_path):
outfile = str(tmp_path / "temp.tif")
with Image.open("Tests/images/hopper.tif") as im:
for dpi in (72.2, 72.8):
im.save(outfile, dpi=(dpi, dpi))
im.save(outfile, dpi=(72.2, 72.2))

with Image.open(outfile) as reloaded:
reloaded.load()
assert (round(dpi), round(dpi)) == reloaded.info["dpi"]
with Image.open(outfile) as reloaded:
for dpi in reloaded.info["dpi"]:
assert float(dpi) == 72.2

def test_save_setting_missing_resolution(self):
b = BytesIO()
Expand Down
20 changes: 15 additions & 5 deletions src/PIL/TiffImagePlugin.py
Expand Up @@ -358,6 +358,16 @@ def __eq__(self, other):
other = other._val
return self._val == other

def __getstate__(self):
return [self._val, self._numerator, self._denominator]

def __setstate__(self, state):
IFDRational.__init__(self, 0)
_val, _numerator, _denominator = state
self._val = _val
self._numerator = _numerator
self._denominator = _denominator

def _delegate(op):
def delegate(self, *args):
return getattr(self._val, op)(*args)
Expand Down Expand Up @@ -1284,11 +1294,11 @@ def _setup(self):
if xres and yres:
resunit = self.tag_v2.get(RESOLUTION_UNIT)
if resunit == 2: # dots per inch
self.info["dpi"] = int(xres + 0.5), int(yres + 0.5)
self.info["dpi"] = (xres, yres)
elif resunit == 3: # dots per centimeter. convert to dpi
self.info["dpi"] = int(xres * 2.54 + 0.5), int(yres * 2.54 + 0.5)
self.info["dpi"] = (xres * 2.54, yres * 2.54)
elif resunit is None: # used to default to 1, but now 2)
self.info["dpi"] = int(xres + 0.5), int(yres + 0.5)
self.info["dpi"] = (xres, yres)
# For backward compatibility,
# we also preserve the old behavior
self.info["resolution"] = xres, yres
Expand Down Expand Up @@ -1521,8 +1531,8 @@ def _save(im, fp, filename):
dpi = im.encoderinfo.get("dpi")
if dpi:
ifd[RESOLUTION_UNIT] = 2
ifd[X_RESOLUTION] = int(dpi[0] + 0.5)
ifd[Y_RESOLUTION] = int(dpi[1] + 0.5)
ifd[X_RESOLUTION] = dpi[0]
ifd[Y_RESOLUTION] = dpi[1]

if bits != (1,):
ifd[BITSPERSAMPLE] = bits
Expand Down

0 comments on commit 9bbe53a

Please sign in to comment.