Merge pull request #5476 from radarhere/dpi_rounding

This commit is contained in:
Hugo van Kemenade 2021-05-16 20:00:10 +03:00 committed by GitHub
commit a72ae6823c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 18 additions and 52 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -63,7 +63,7 @@ def test_dpi():
output.seek(0) output.seek(0)
with Image.open(output) as reloaded: with Image.open(output) as reloaded:
assert reloaded.info["dpi"] == dpi assert reloaded.info["dpi"] == (72.008961115161, 72.008961115161)
def test_save_bmp_with_dpi(tmp_path): def test_save_bmp_with_dpi(tmp_path):
@ -71,6 +71,7 @@ def test_save_bmp_with_dpi(tmp_path):
# Arrange # Arrange
outfile = str(tmp_path / "temp.jpg") outfile = str(tmp_path / "temp.jpg")
with Image.open("Tests/images/hopper.bmp") as im: with Image.open("Tests/images/hopper.bmp") as im:
assert im.info["dpi"] == (95.98654816726399, 95.98654816726399)
# Act # Act
im.save(outfile, "JPEG", dpi=im.info["dpi"]) im.save(outfile, "JPEG", dpi=im.info["dpi"])
@ -78,31 +79,17 @@ def test_save_bmp_with_dpi(tmp_path):
# Assert # Assert
with Image.open(outfile) as reloaded: with Image.open(outfile) as reloaded:
reloaded.load() reloaded.load()
assert im.info["dpi"] == reloaded.info["dpi"] assert reloaded.info["dpi"] == (96, 96)
assert im.size == reloaded.size assert reloaded.size == im.size
assert reloaded.format == "JPEG" assert reloaded.format == "JPEG"
def test_load_dpi_rounding(): def test_save_float_dpi(tmp_path):
# Round up
with Image.open("Tests/images/hopper.bmp") as im:
assert im.info["dpi"] == (96, 96)
# Round down
with Image.open("Tests/images/hopper_roundDown.bmp") as im:
assert im.info["dpi"] == (72, 72)
def test_save_dpi_rounding(tmp_path):
outfile = str(tmp_path / "temp.bmp") outfile = str(tmp_path / "temp.bmp")
with Image.open("Tests/images/hopper.bmp") as im: with Image.open("Tests/images/hopper.bmp") as im:
im.save(outfile, dpi=(72.2, 72.2)) im.save(outfile, dpi=(72.21216100543306, 72.21216100543306))
with Image.open(outfile) as reloaded: with Image.open(outfile) as reloaded:
assert reloaded.info["dpi"] == (72, 72) assert reloaded.info["dpi"] == (72.21216100543306, 72.21216100543306)
im.save(outfile, dpi=(72.8, 72.8))
with Image.open(outfile) as reloaded:
assert reloaded.info["dpi"] == (73, 73)
def test_load_dib(): def test_load_dib():

View File

@ -656,15 +656,6 @@ class TestFileJpeg:
reloaded.load() reloaded.load()
assert im.info["dpi"] == reloaded.info["dpi"] assert im.info["dpi"] == reloaded.info["dpi"]
def test_load_dpi_rounding(self):
# Round up
with Image.open("Tests/images/iptc_roundUp.jpg") as im:
assert im.info["dpi"] == (44, 44)
# Round down
with Image.open("Tests/images/iptc_roundDown.jpg") as im:
assert im.info["dpi"] == (2, 2)
def test_save_dpi_rounding(self, tmp_path): def test_save_dpi_rounding(self, tmp_path):
outfile = str(tmp_path / "temp.jpg") outfile = str(tmp_path / "temp.jpg")
with Image.open("Tests/images/hopper.jpg") as im: with Image.open("Tests/images/hopper.jpg") as im:

View File

@ -386,25 +386,12 @@ class TestFilePng:
# Check dpi roundtripping # Check dpi roundtripping
with Image.open(TEST_PNG_FILE) as im: with Image.open(TEST_PNG_FILE) as im:
im = roundtrip(im, dpi=(100, 100)) im = roundtrip(im, dpi=(100.33, 100.33))
assert im.info["dpi"] == (100, 100) assert im.info["dpi"] == (100.33, 100.33)
def test_load_dpi_rounding(self): def test_load_float_dpi(self):
# Round up
with Image.open(TEST_PNG_FILE) as im: with Image.open(TEST_PNG_FILE) as im:
assert im.info["dpi"] == (96, 96) assert im.info["dpi"] == (95.9866, 95.9866)
# Round down
with Image.open("Tests/images/icc_profile_none.png") as im:
assert im.info["dpi"] == (72, 72)
def test_save_dpi_rounding(self):
with Image.open(TEST_PNG_FILE) as im:
im = roundtrip(im, dpi=(72.2, 72.2))
assert im.info["dpi"] == (72, 72)
im = roundtrip(im, dpi=(72.8, 72.8))
assert im.info["dpi"] == (73, 73)
def test_roundtrip_text(self): def test_roundtrip_text(self):
# Check text roundtripping # Check text roundtripping

View File

@ -115,9 +115,7 @@ class BmpImageFile(ImageFile.ImageFile):
) )
file_info["colors"] = i32(header_data, 28) file_info["colors"] = i32(header_data, 28)
file_info["palette_padding"] = 4 file_info["palette_padding"] = 4
self.info["dpi"] = tuple( self.info["dpi"] = tuple(x / 39.3701 for x in file_info["pixels_per_meter"])
int(x / 39.3701 + 0.5) for x in file_info["pixels_per_meter"]
)
if file_info["compression"] == self.BITFIELDS: if file_info["compression"] == self.BITFIELDS:
if len(header_data) >= 52: if len(header_data) >= 52:
for idx, mask in enumerate( for idx, mask in enumerate(

View File

@ -33,6 +33,7 @@
# #
import array import array
import io import io
import math
import os import os
import struct import struct
import subprocess import subprocess
@ -162,15 +163,17 @@ def APP(self, marker):
dpi = float(x_resolution[0]) / x_resolution[1] dpi = float(x_resolution[0]) / x_resolution[1]
except TypeError: except TypeError:
dpi = x_resolution dpi = x_resolution
if math.isnan(dpi):
raise ValueError
if resolution_unit == 3: # cm if resolution_unit == 3: # cm
# 1 dpcm = 2.54 dpi # 1 dpcm = 2.54 dpi
dpi *= 2.54 dpi *= 2.54
self.info["dpi"] = int(dpi + 0.5), int(dpi + 0.5) self.info["dpi"] = dpi, dpi
except (KeyError, SyntaxError, ValueError, ZeroDivisionError): except (KeyError, SyntaxError, ValueError, ZeroDivisionError):
# SyntaxError for invalid/unreadable EXIF # SyntaxError for invalid/unreadable EXIF
# KeyError for dpi not included # KeyError for dpi not included
# ZeroDivisionError for invalid dpi rational value # ZeroDivisionError for invalid dpi rational value
# ValueError for x_resolution[0] being an invalid float # ValueError for dpi being an invalid float
self.info["dpi"] = 72, 72 self.info["dpi"] = 72, 72

View File

@ -500,7 +500,7 @@ class PngStream(ChunkStream):
px, py = i32(s, 0), i32(s, 4) px, py = i32(s, 0), i32(s, 4)
unit = s[8] unit = s[8]
if unit == 1: # meter if unit == 1: # meter
dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5) dpi = px * 0.0254, py * 0.0254
self.im_info["dpi"] = dpi self.im_info["dpi"] = dpi
elif unit == 0: elif unit == 0:
self.im_info["aspect"] = px, py self.im_info["aspect"] = px, py