Added scale argument to IcnsImageFile load()

This commit is contained in:
Andrew Murray 2024-09-06 11:37:12 +10:00
parent 6377321625
commit e625f73119
3 changed files with 48 additions and 31 deletions

View File

@ -63,8 +63,8 @@ def test_save_append_images(tmp_path: Path) -> None:
assert_image_similar_tofile(im, temp_file, 1) assert_image_similar_tofile(im, temp_file, 1)
with Image.open(temp_file) as reread: with Image.open(temp_file) as reread:
reread.size = (16, 16, 2) reread.size = (16, 16)
reread.load() reread.load(2)
assert_image_equal(reread, provided_im) assert_image_equal(reread, provided_im)
@ -92,9 +92,15 @@ def test_sizes() -> None:
assert im.mode == "RGBA" assert im.mode == "RGBA"
assert im.size == (wr, hr) assert im.size == (wr, hr)
# Test using load() with scale
im.size = (w, h)
im.load(scale=r)
assert im.mode == "RGBA"
assert im.size == (wr, hr)
# Check that we cannot load an incorrect size # Check that we cannot load an incorrect size
with pytest.raises(ValueError): with pytest.raises(ValueError):
im.size = (1, 1) im.size = (1, 2)
def test_older_icon() -> None: def test_older_icon() -> None:
@ -105,8 +111,8 @@ def test_older_icon() -> None:
wr = w * r wr = w * r
hr = h * r hr = h * r
with Image.open("Tests/images/pillow2.icns") as im2: with Image.open("Tests/images/pillow2.icns") as im2:
im2.size = (w, h, r) im2.size = (w, h)
im2.load() im2.load(r)
assert im2.mode == "RGBA" assert im2.mode == "RGBA"
assert im2.size == (wr, hr) assert im2.size == (wr, hr)
@ -122,8 +128,8 @@ def test_jp2_icon() -> None:
wr = w * r wr = w * r
hr = h * r hr = h * r
with Image.open("Tests/images/pillow3.icns") as im2: with Image.open("Tests/images/pillow3.icns") as im2:
im2.size = (w, h, r) im2.size = (w, h)
im2.load() im2.load(r)
assert im2.mode == "RGBA" assert im2.mode == "RGBA"
assert im2.size == (wr, hr) assert im2.size == (wr, hr)

View File

@ -331,6 +331,18 @@ sets the following :py:attr:`~PIL.Image.Image.info` property:
ask for ``(512, 512, 2)``, the final value of ask for ``(512, 512, 2)``, the final value of
:py:attr:`~PIL.Image.Image.size` will be ``(1024, 1024)``). :py:attr:`~PIL.Image.Image.size` will be ``(1024, 1024)``).
.. _icns-loading:
Loading
~~~~~~~
You can call the :py:meth:`~PIL.Image.Image.load` method with the following parameter.
**scale**
Affects the scale of the resultant image. If the size is set to ``(512, 512)``,
after loading at scale 2, the final value of :py:attr:`~PIL.Image.Image.size` will
be ``(1024, 1024)``.
.. _icns-saving: .. _icns-saving:
Saving Saving

View File

@ -281,31 +281,30 @@ class IcnsImageFile(ImageFile.ImageFile):
@size.setter @size.setter
def size(self, value) -> None: def size(self, value) -> None:
info_size = value if len(value) == 3:
if info_size not in self.info["sizes"] and len(info_size) == 2: if value in self.info["sizes"]:
info_size = (info_size[0], info_size[1], 1) self._size = value
if ( return
info_size not in self.info["sizes"] else:
and len(info_size) == 3 # Check that a matching size exists,
and info_size[2] == 1 # or that there is a scale that would create a size that matches
): for size in self.info["sizes"]:
simple_sizes = [ simple_size = size[0] * size[2], size[1] * size[2]
(size[0] * size[2], size[1] * size[2]) for size in self.info["sizes"] scale = simple_size[0] // value[0]
] if simple_size[1] / value[1] == scale:
if value in simple_sizes: self._size = value
info_size = self.info["sizes"][simple_sizes.index(value)] return
if info_size not in self.info["sizes"]:
msg = "This is not one of the allowed sizes of this image" msg = "This is not one of the allowed sizes of this image"
raise ValueError(msg) raise ValueError(msg)
self._size = value
def load(self) -> Image.core.PixelAccess | None: def load(self, scale: int | None = None) -> Image.core.PixelAccess | None:
if len(self.size) == 3: if scale is not None or len(self.size) == 3:
self.best_size = self.size if scale is None and len(self.size) == 3:
self.size = ( scale = self.size[2]
self.best_size[0] * self.best_size[2], assert scale is not None
self.best_size[1] * self.best_size[2], width, height = self.size[:2]
) self.size = width * scale, height * scale
self.best_size = width, height, scale
px = Image.Image.load(self) px = Image.Image.load(self)
if self._im is not None and self.im.size == self.size: if self._im is not None and self.im.size == self.size: