mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-23 06:23:10 +03:00
Allow loading of EMF images at a given DPI (#8536)
Co-authored-by: Andrew Murray <radarhere@users.noreply.github.com>
This commit is contained in:
parent
2579973815
commit
6d42449788
BIN
Tests/images/drawing_emf_ref_72_144.png
Normal file
BIN
Tests/images/drawing_emf_ref_72_144.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 984 B |
|
@ -97,6 +97,20 @@ def test_load_set_dpi() -> None:
|
||||||
|
|
||||||
assert_image_similar_tofile(im, "Tests/images/drawing_wmf_ref_144.png", 2.1)
|
assert_image_similar_tofile(im, "Tests/images/drawing_wmf_ref_144.png", 2.1)
|
||||||
|
|
||||||
|
with Image.open("Tests/images/drawing.emf") as im:
|
||||||
|
assert im.size == (1625, 1625)
|
||||||
|
|
||||||
|
if not hasattr(Image.core, "drawwmf"):
|
||||||
|
return
|
||||||
|
im.load(im.info["dpi"])
|
||||||
|
assert im.size == (1625, 1625)
|
||||||
|
|
||||||
|
with Image.open("Tests/images/drawing.emf") as im:
|
||||||
|
im.load((72, 144))
|
||||||
|
assert im.size == (82, 164)
|
||||||
|
|
||||||
|
assert_image_equal_tofile(im, "Tests/images/drawing_emf_ref_72_144.png")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("ext", (".wmf", ".emf"))
|
@pytest.mark.parametrize("ext", (".wmf", ".emf"))
|
||||||
def test_save(ext: str, tmp_path: Path) -> None:
|
def test_save(ext: str, tmp_path: Path) -> None:
|
||||||
|
|
|
@ -80,8 +80,6 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
||||||
format_description = "Windows Metafile"
|
format_description = "Windows Metafile"
|
||||||
|
|
||||||
def _open(self) -> None:
|
def _open(self) -> None:
|
||||||
self._inch = None
|
|
||||||
|
|
||||||
# check placable header
|
# check placable header
|
||||||
s = self.fp.read(80)
|
s = self.fp.read(80)
|
||||||
|
|
||||||
|
@ -89,10 +87,11 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
||||||
# placeable windows metafile
|
# placeable windows metafile
|
||||||
|
|
||||||
# get units per inch
|
# get units per inch
|
||||||
self._inch = word(s, 14)
|
inch = word(s, 14)
|
||||||
if self._inch == 0:
|
if inch == 0:
|
||||||
msg = "Invalid inch"
|
msg = "Invalid inch"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
self._inch: tuple[float, float] = inch, inch
|
||||||
|
|
||||||
# get bounding box
|
# get bounding box
|
||||||
x0 = short(s, 6)
|
x0 = short(s, 6)
|
||||||
|
@ -103,8 +102,8 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
||||||
# normalize size to 72 dots per inch
|
# normalize size to 72 dots per inch
|
||||||
self.info["dpi"] = 72
|
self.info["dpi"] = 72
|
||||||
size = (
|
size = (
|
||||||
(x1 - x0) * self.info["dpi"] // self._inch,
|
(x1 - x0) * self.info["dpi"] // inch,
|
||||||
(y1 - y0) * self.info["dpi"] // self._inch,
|
(y1 - y0) * self.info["dpi"] // inch,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.info["wmf_bbox"] = x0, y0, x1, y1
|
self.info["wmf_bbox"] = x0, y0, x1, y1
|
||||||
|
@ -138,6 +137,7 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
||||||
self.info["dpi"] = xdpi
|
self.info["dpi"] = xdpi
|
||||||
else:
|
else:
|
||||||
self.info["dpi"] = xdpi, ydpi
|
self.info["dpi"] = xdpi, ydpi
|
||||||
|
self._inch = xdpi, ydpi
|
||||||
|
|
||||||
else:
|
else:
|
||||||
msg = "Unsupported file format"
|
msg = "Unsupported file format"
|
||||||
|
@ -153,13 +153,17 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
||||||
def _load(self) -> ImageFile.StubHandler | None:
|
def _load(self) -> ImageFile.StubHandler | None:
|
||||||
return _handler
|
return _handler
|
||||||
|
|
||||||
def load(self, dpi: int | None = None) -> Image.core.PixelAccess | None:
|
def load(
|
||||||
if dpi is not None and self._inch is not None:
|
self, dpi: float | tuple[float, float] | None = None
|
||||||
|
) -> Image.core.PixelAccess | None:
|
||||||
|
if dpi is not None:
|
||||||
self.info["dpi"] = dpi
|
self.info["dpi"] = dpi
|
||||||
x0, y0, x1, y1 = self.info["wmf_bbox"]
|
x0, y0, x1, y1 = self.info["wmf_bbox"]
|
||||||
|
if not isinstance(dpi, tuple):
|
||||||
|
dpi = dpi, dpi
|
||||||
self._size = (
|
self._size = (
|
||||||
(x1 - x0) * self.info["dpi"] // self._inch,
|
int((x1 - x0) * dpi[0] / self._inch[0]),
|
||||||
(y1 - y0) * self.info["dpi"] // self._inch,
|
int((y1 - y0) * dpi[1] / self._inch[1]),
|
||||||
)
|
)
|
||||||
return super().load()
|
return super().load()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user