mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-04-27 12:33:41 +03:00
Merge pull request #4474 from radarhere/reduce2
Prevent masking Image reduce method in Jpeg2K
This commit is contained in:
commit
5a511c6a8b
|
@ -127,10 +127,17 @@ def test_prog_res_rt():
|
||||||
|
|
||||||
def test_reduce():
|
def test_reduce():
|
||||||
with Image.open("Tests/images/test-card-lossless.jp2") as im:
|
with Image.open("Tests/images/test-card-lossless.jp2") as im:
|
||||||
|
assert callable(im.reduce)
|
||||||
|
|
||||||
im.reduce = 2
|
im.reduce = 2
|
||||||
|
assert im.reduce == 2
|
||||||
|
|
||||||
im.load()
|
im.load()
|
||||||
assert im.size == (160, 120)
|
assert im.size == (160, 120)
|
||||||
|
|
||||||
|
im.thumbnail((40, 40))
|
||||||
|
assert im.size == (40, 30)
|
||||||
|
|
||||||
|
|
||||||
def test_layers_type(tmp_path):
|
def test_layers_type(tmp_path):
|
||||||
outfile = str(tmp_path / "temp_layers.jp2")
|
outfile = str(tmp_path / "temp_layers.jp2")
|
||||||
|
|
|
@ -3,6 +3,9 @@ from PIL import Image, ImageMath, ImageMode
|
||||||
|
|
||||||
from .helper import convert_to_comparable
|
from .helper import convert_to_comparable
|
||||||
|
|
||||||
|
codecs = dir(Image.core)
|
||||||
|
|
||||||
|
|
||||||
# There are several internal implementations
|
# There are several internal implementations
|
||||||
remarkable_factors = [
|
remarkable_factors = [
|
||||||
# special implementations
|
# special implementations
|
||||||
|
@ -247,3 +250,11 @@ def test_mode_F():
|
||||||
for factor in remarkable_factors:
|
for factor in remarkable_factors:
|
||||||
compare_reduce_with_reference(im, factor, 0, 0)
|
compare_reduce_with_reference(im, factor, 0, 0)
|
||||||
compare_reduce_with_box(im, factor)
|
compare_reduce_with_box(im, factor)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
"jpeg2k_decoder" not in codecs, reason="JPEG 2000 support not available"
|
||||||
|
)
|
||||||
|
def test_jpeg2k():
|
||||||
|
with Image.open("Tests/images/test-card-lossless.jp2") as im:
|
||||||
|
assert im.reduce(2).size == (320, 240)
|
||||||
|
|
|
@ -1866,7 +1866,11 @@ class Image:
|
||||||
factor_y = int((box[3] - box[1]) / size[1] / reducing_gap) or 1
|
factor_y = int((box[3] - box[1]) / size[1] / reducing_gap) or 1
|
||||||
if factor_x > 1 or factor_y > 1:
|
if factor_x > 1 or factor_y > 1:
|
||||||
reduce_box = self._get_safe_box(size, resample, box)
|
reduce_box = self._get_safe_box(size, resample, box)
|
||||||
self = self.reduce((factor_x, factor_y), box=reduce_box)
|
factor = (factor_x, factor_y)
|
||||||
|
if callable(self.reduce):
|
||||||
|
self = self.reduce(factor, box=reduce_box)
|
||||||
|
else:
|
||||||
|
self = Image.reduce(self, factor, box=reduce_box)
|
||||||
box = (
|
box = (
|
||||||
(box[0] - reduce_box[0]) / factor_x,
|
(box[0] - reduce_box[0]) / factor_x,
|
||||||
(box[1] - reduce_box[1]) / factor_y,
|
(box[1] - reduce_box[1]) / factor_y,
|
||||||
|
|
|
@ -176,7 +176,7 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
|
||||||
if self.size is None or self.mode is None:
|
if self.size is None or self.mode is None:
|
||||||
raise SyntaxError("unable to determine size/mode")
|
raise SyntaxError("unable to determine size/mode")
|
||||||
|
|
||||||
self.reduce = 0
|
self._reduce = 0
|
||||||
self.layers = 0
|
self.layers = 0
|
||||||
|
|
||||||
fd = -1
|
fd = -1
|
||||||
|
@ -200,23 +200,33 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
|
||||||
"jpeg2k",
|
"jpeg2k",
|
||||||
(0, 0) + self.size,
|
(0, 0) + self.size,
|
||||||
0,
|
0,
|
||||||
(self.codec, self.reduce, self.layers, fd, length),
|
(self.codec, self._reduce, self.layers, fd, length),
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reduce(self):
|
||||||
|
# https://github.com/python-pillow/Pillow/issues/4343 found that the
|
||||||
|
# new Image 'reduce' method was shadowed by this plugin's 'reduce'
|
||||||
|
# property. This attempts to allow for both scenarios
|
||||||
|
return self._reduce or super().reduce
|
||||||
|
|
||||||
|
@reduce.setter
|
||||||
|
def reduce(self, value):
|
||||||
|
self._reduce = value
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
if self.reduce:
|
if self.tile and self._reduce:
|
||||||
power = 1 << self.reduce
|
power = 1 << self._reduce
|
||||||
adjust = power >> 1
|
adjust = power >> 1
|
||||||
self._size = (
|
self._size = (
|
||||||
int((self.size[0] + adjust) / power),
|
int((self.size[0] + adjust) / power),
|
||||||
int((self.size[1] + adjust) / power),
|
int((self.size[1] + adjust) / power),
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.tile:
|
|
||||||
# Update the reduce and layers settings
|
# Update the reduce and layers settings
|
||||||
t = self.tile[0]
|
t = self.tile[0]
|
||||||
t3 = (t[3][0], self.reduce, self.layers, t[3][3], t[3][4])
|
t3 = (t[3][0], self._reduce, self.layers, t[3][3], t[3][4])
|
||||||
self.tile = [(t[0], (0, 0) + self.size, t[2], t3)]
|
self.tile = [(t[0], (0, 0) + self.size, t[2], t3)]
|
||||||
|
|
||||||
return ImageFile.ImageFile.load(self)
|
return ImageFile.ImageFile.load(self)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user