Skip to content

Commit

Permalink
Allow loading of EMF images at a given DPI
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Nov 5, 2024
1 parent 7fe56d6 commit 20105aa
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
Binary file added Tests/images/drawing_emf_ref_72_144.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion Tests/test_file_wmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from PIL import Image, ImageFile, WmfImagePlugin

from .helper import assert_image_similar_tofile, hopper
from .helper import assert_image_equal_tofile, assert_image_similar_tofile, hopper


def test_load_raw() -> None:
Expand Down Expand Up @@ -79,6 +79,20 @@ def test_load_set_dpi() -> None:

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"))
def test_save(ext: str, tmp_path: Path) -> None:
Expand Down
22 changes: 13 additions & 9 deletions src/PIL/WmfImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,15 @@ class WmfStubImageFile(ImageFile.StubImageFile):
format_description = "Windows Metafile"

def _open(self) -> None:
self._inch = None

# check placable header
s = self.fp.read(80)

if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00":
# placeable windows metafile

# get units per inch
self._inch = word(s, 14)
inch = word(s, 14)
self._inch: tuple[float, float] = inch, inch

# get bounding box
x0 = short(s, 6)
Expand All @@ -102,8 +101,8 @@ def _open(self) -> None:
# normalize size to 72 dots per inch
self.info["dpi"] = 72
size = (
(x1 - x0) * self.info["dpi"] // self._inch,
(y1 - y0) * self.info["dpi"] // self._inch,
(x1 - x0) * self.info["dpi"] // inch,
(y1 - y0) * self.info["dpi"] // inch,
)

self.info["wmf_bbox"] = x0, y0, x1, y1
Expand Down Expand Up @@ -137,6 +136,7 @@ def _open(self) -> None:
self.info["dpi"] = xdpi
else:
self.info["dpi"] = xdpi, ydpi
self._inch = xdpi, ydpi

else:
msg = "Unsupported file format"
Expand All @@ -152,13 +152,17 @@ def _open(self) -> None:
def _load(self) -> ImageFile.StubHandler | None:
return _handler

def load(self, dpi: int | None = None) -> Image.core.PixelAccess | None:
if dpi is not None and self._inch is not None:
def load(
self, dpi: float | tuple[float, float] | None = None
) -> Image.core.PixelAccess | None:
if dpi is not None:
self.info["dpi"] = dpi
x0, y0, x1, y1 = self.info["wmf_bbox"]
if not isinstance(dpi, tuple):
dpi = dpi, dpi
self._size = (
(x1 - x0) * self.info["dpi"] // self._inch,
(y1 - y0) * self.info["dpi"] // self._inch,
int((x1 - x0) * dpi[0] / self._inch[0]),
int((y1 - y0) * dpi[1] / self._inch[1]),
)
return super().load()

Expand Down

0 comments on commit 20105aa

Please sign in to comment.