mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-11 07:44:46 +03:00
use tuple or set instead of list in tests
This commit is contained in:
parent
0a827f0c77
commit
3f045ea194
|
@ -9,9 +9,9 @@ base = os.path.join("Tests", "images", "bmp")
|
||||||
|
|
||||||
|
|
||||||
def get_files(d, ext=".bmp"):
|
def get_files(d, ext=".bmp"):
|
||||||
return [
|
return (
|
||||||
os.path.join(base, d, f) for f in os.listdir(os.path.join(base, d)) if ext in f
|
os.path.join(base, d, f) for f in os.listdir(os.path.join(base, d)) if ext in f
|
||||||
]
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_bad():
|
def test_bad():
|
||||||
|
@ -30,7 +30,7 @@ def test_bad():
|
||||||
def test_questionable():
|
def test_questionable():
|
||||||
"""These shouldn't crash/dos, but it's not well defined that these
|
"""These shouldn't crash/dos, but it's not well defined that these
|
||||||
are in spec"""
|
are in spec"""
|
||||||
supported = [
|
supported = {
|
||||||
"pal8os2v2.bmp",
|
"pal8os2v2.bmp",
|
||||||
"rgb24prof.bmp",
|
"rgb24prof.bmp",
|
||||||
"pal1p1.bmp",
|
"pal1p1.bmp",
|
||||||
|
@ -42,7 +42,7 @@ def test_questionable():
|
||||||
"pal8os2sp.bmp",
|
"pal8os2sp.bmp",
|
||||||
"pal8rletrns.bmp",
|
"pal8rletrns.bmp",
|
||||||
"rgb32bf-xbgr.bmp",
|
"rgb32bf-xbgr.bmp",
|
||||||
]
|
}
|
||||||
for f in get_files("q"):
|
for f in get_files("q"):
|
||||||
try:
|
try:
|
||||||
with Image.open(f) as im:
|
with Image.open(f) as im:
|
||||||
|
|
|
@ -27,8 +27,9 @@ def box_blur(image, radius=1, n=1):
|
||||||
|
|
||||||
def assert_image(im, data, delta=0):
|
def assert_image(im, data, delta=0):
|
||||||
it = iter(im.getdata())
|
it = iter(im.getdata())
|
||||||
|
width_range = range(im.size[0])
|
||||||
for data_row in data:
|
for data_row in data:
|
||||||
im_row = [next(it) for _ in range(im.size[0])]
|
im_row = [next(it) for _ in width_range]
|
||||||
if any(abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row)):
|
if any(abs(data_v - im_v) > delta for data_v, im_v in zip(data_row, im_row)):
|
||||||
assert im_row == data_row
|
assert im_row == data_row
|
||||||
with pytest.raises(StopIteration):
|
with pytest.raises(StopIteration):
|
||||||
|
@ -67,15 +68,15 @@ def test_radius_0():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
0,
|
0,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[210, 50, 20, 10, 220, 230, 80],
|
(210, 50, 20, 10, 220, 230, 80),
|
||||||
[190, 210, 20, 180, 170, 40, 110],
|
(190, 210, 20, 180, 170, 40, 110),
|
||||||
[120, 210, 250, 60, 220, 0, 220],
|
(120, 210, 250, 60, 220, 0, 220),
|
||||||
[220, 40, 230, 80, 130, 250, 40],
|
(220, 40, 230, 80, 130, 250, 40),
|
||||||
[250, 0, 80, 30, 60, 20, 110],
|
(250, 0, 80, 30, 60, 20, 110),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,15 +84,15 @@ def test_radius_0_02():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
0.02,
|
0.02,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[206, 55, 20, 17, 215, 223, 83],
|
(206, 55, 20, 17, 215, 223, 83),
|
||||||
[189, 203, 31, 171, 169, 46, 110],
|
(189, 203, 31, 171, 169, 46, 110),
|
||||||
[125, 206, 241, 69, 210, 13, 210],
|
(125, 206, 241, 69, 210, 13, 210),
|
||||||
[215, 49, 221, 82, 131, 235, 48],
|
(215, 49, 221, 82, 131, 235, 48),
|
||||||
[244, 7, 80, 32, 60, 27, 107],
|
(244, 7, 80, 32, 60, 27, 107),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=2,
|
delta=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -100,15 +101,15 @@ def test_radius_0_05():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
0.05,
|
0.05,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[202, 62, 22, 27, 209, 215, 88],
|
(202, 62, 22, 27, 209, 215, 88),
|
||||||
[188, 194, 44, 161, 168, 56, 111],
|
(188, 194, 44, 161, 168, 56, 111),
|
||||||
[131, 201, 229, 81, 198, 31, 198],
|
(131, 201, 229, 81, 198, 31, 198),
|
||||||
[209, 62, 209, 86, 133, 216, 59],
|
(209, 62, 209, 86, 133, 216, 59),
|
||||||
[237, 17, 80, 36, 60, 35, 103],
|
(237, 17, 80, 36, 60, 35, 103),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=2,
|
delta=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -117,15 +118,15 @@ def test_radius_0_1():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
0.1,
|
0.1,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[196, 72, 24, 40, 200, 203, 93],
|
(196, 72, 24, 40, 200, 203, 93),
|
||||||
[187, 183, 62, 148, 166, 68, 111],
|
(187, 183, 62, 148, 166, 68, 111),
|
||||||
[139, 193, 213, 96, 182, 54, 182],
|
(139, 193, 213, 96, 182, 54, 182),
|
||||||
[201, 78, 193, 91, 133, 191, 73],
|
(201, 78, 193, 91, 133, 191, 73),
|
||||||
[227, 31, 80, 42, 61, 47, 99],
|
(227, 31, 80, 42, 61, 47, 99),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -134,15 +135,15 @@ def test_radius_0_5():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
0.5,
|
0.5,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[176, 101, 46, 83, 163, 165, 111],
|
(176, 101, 46, 83, 163, 165, 111),
|
||||||
[176, 149, 108, 122, 144, 120, 117],
|
(176, 149, 108, 122, 144, 120, 117),
|
||||||
[164, 171, 159, 141, 134, 119, 129],
|
(164, 171, 159, 141, 134, 119, 129),
|
||||||
[170, 136, 133, 114, 116, 124, 109],
|
(170, 136, 133, 114, 116, 124, 109),
|
||||||
[184, 95, 72, 70, 69, 81, 89],
|
(184, 95, 72, 70, 69, 81, 89),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -151,15 +152,15 @@ def test_radius_1():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
1,
|
1,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[170, 109, 63, 97, 146, 153, 116],
|
(170, 109, 63, 97, 146, 153, 116),
|
||||||
[168, 142, 112, 128, 126, 143, 121],
|
(168, 142, 112, 128, 126, 143, 121),
|
||||||
[169, 166, 142, 149, 126, 131, 114],
|
(169, 166, 142, 149, 126, 131, 114),
|
||||||
[159, 156, 109, 127, 94, 117, 112],
|
(159, 156, 109, 127, 94, 117, 112),
|
||||||
[164, 128, 63, 87, 76, 89, 90],
|
(164, 128, 63, 87, 76, 89, 90),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -168,15 +169,15 @@ def test_radius_1_5():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
1.5,
|
1.5,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[155, 120, 105, 112, 124, 137, 130],
|
(155, 120, 105, 112, 124, 137, 130),
|
||||||
[160, 136, 124, 125, 127, 134, 130],
|
(160, 136, 124, 125, 127, 134, 130),
|
||||||
[166, 147, 130, 125, 120, 121, 119],
|
(166, 147, 130, 125, 120, 121, 119),
|
||||||
[168, 145, 119, 109, 103, 105, 110],
|
(168, 145, 119, 109, 103, 105, 110),
|
||||||
[168, 134, 96, 85, 85, 89, 97],
|
(168, 134, 96, 85, 85, 89, 97),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -185,15 +186,15 @@ def test_radius_bigger_then_half():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
3,
|
3,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[144, 145, 142, 128, 114, 115, 117],
|
(144, 145, 142, 128, 114, 115, 117),
|
||||||
[148, 145, 137, 122, 109, 111, 112],
|
(148, 145, 137, 122, 109, 111, 112),
|
||||||
[152, 145, 131, 117, 103, 107, 108],
|
(152, 145, 131, 117, 103, 107, 108),
|
||||||
[156, 144, 126, 111, 97, 102, 103],
|
(156, 144, 126, 111, 97, 102, 103),
|
||||||
[160, 144, 121, 106, 92, 98, 99],
|
(160, 144, 121, 106, 92, 98, 99),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -202,13 +203,13 @@ def test_radius_bigger_then_width():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
10,
|
10,
|
||||||
[
|
(
|
||||||
[158, 153, 147, 141, 135, 129, 123],
|
(158, 153, 147, 141, 135, 129, 123),
|
||||||
[159, 153, 147, 141, 136, 130, 124],
|
(159, 153, 147, 141, 136, 130, 124),
|
||||||
[159, 154, 148, 142, 136, 130, 124],
|
(159, 154, 148, 142, 136, 130, 124),
|
||||||
[160, 154, 148, 142, 137, 131, 125],
|
(160, 154, 148, 142, 137, 131, 125),
|
||||||
[160, 155, 149, 143, 137, 131, 125],
|
(160, 155, 149, 143, 137, 131, 125),
|
||||||
],
|
),
|
||||||
delta=0,
|
delta=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -217,13 +218,13 @@ def test_extreme_large_radius():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
600,
|
600,
|
||||||
[
|
(
|
||||||
[162, 162, 162, 162, 162, 162, 162],
|
(162, 162, 162, 162, 162, 162, 162),
|
||||||
[162, 162, 162, 162, 162, 162, 162],
|
(162, 162, 162, 162, 162, 162, 162),
|
||||||
[162, 162, 162, 162, 162, 162, 162],
|
(162, 162, 162, 162, 162, 162, 162),
|
||||||
[162, 162, 162, 162, 162, 162, 162],
|
(162, 162, 162, 162, 162, 162, 162),
|
||||||
[162, 162, 162, 162, 162, 162, 162],
|
(162, 162, 162, 162, 162, 162, 162),
|
||||||
],
|
),
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -232,15 +233,15 @@ def test_two_passes():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
1,
|
1,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[153, 123, 102, 109, 132, 135, 129],
|
(153, 123, 102, 109, 132, 135, 129),
|
||||||
[159, 138, 123, 121, 133, 131, 126],
|
(159, 138, 123, 121, 133, 131, 126),
|
||||||
[162, 147, 136, 124, 127, 121, 121],
|
(162, 147, 136, 124, 127, 121, 121),
|
||||||
[159, 140, 125, 108, 111, 106, 108],
|
(159, 140, 125, 108, 111, 106, 108),
|
||||||
[154, 126, 105, 87, 94, 93, 97],
|
(154, 126, 105, 87, 94, 93, 97),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
passes=2,
|
passes=2,
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
@ -250,15 +251,15 @@ def test_three_passes():
|
||||||
assert_blur(
|
assert_blur(
|
||||||
sample,
|
sample,
|
||||||
1,
|
1,
|
||||||
[
|
(
|
||||||
# fmt: off
|
# fmt: off
|
||||||
[146, 131, 116, 118, 126, 131, 130],
|
(146, 131, 116, 118, 126, 131, 130),
|
||||||
[151, 138, 125, 123, 126, 128, 127],
|
(151, 138, 125, 123, 126, 128, 127),
|
||||||
[154, 143, 129, 123, 120, 120, 119],
|
(154, 143, 129, 123, 120, 120, 119),
|
||||||
[152, 139, 122, 113, 108, 108, 108],
|
(152, 139, 122, 113, 108, 108, 108),
|
||||||
[148, 132, 112, 102, 97, 99, 100],
|
(148, 132, 112, 102, 97, 99, 100),
|
||||||
# fmt: on
|
# fmt: on
|
||||||
],
|
),
|
||||||
passes=3,
|
passes=3,
|
||||||
delta=1,
|
delta=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,13 +20,13 @@ class TestColorLut3DCoreAPI:
|
||||||
size_1d, size_2d, size_3d = (size, size, size)
|
size_1d, size_2d, size_3d = (size, size, size)
|
||||||
|
|
||||||
table = [
|
table = [
|
||||||
[
|
(
|
||||||
r / (size_1d - 1) if size_1d != 1 else 0,
|
r / (size_1d - 1) if size_1d != 1 else 0,
|
||||||
g / (size_2d - 1) if size_2d != 1 else 0,
|
g / (size_2d - 1) if size_2d != 1 else 0,
|
||||||
b / (size_3d - 1) if size_3d != 1 else 0,
|
b / (size_3d - 1) if size_3d != 1 else 0,
|
||||||
r / (size_1d - 1) if size_1d != 1 else 0,
|
r / (size_1d - 1) if size_1d != 1 else 0,
|
||||||
g / (size_2d - 1) if size_2d != 1 else 0,
|
g / (size_2d - 1) if size_2d != 1 else 0,
|
||||||
][:channels]
|
)[:channels]
|
||||||
for b in range(size_3d)
|
for b in range(size_3d)
|
||||||
for g in range(size_2d)
|
for g in range(size_2d)
|
||||||
for r in range(size_1d)
|
for r in range(size_1d)
|
||||||
|
@ -83,17 +83,17 @@ class TestColorLut3DCoreAPI:
|
||||||
|
|
||||||
with pytest.raises(ValueError, match=r"size1D \* size2D \* size3D"):
|
with pytest.raises(ValueError, match=r"size1D \* size2D \* size3D"):
|
||||||
im.im.color_lut_3d(
|
im.im.color_lut_3d(
|
||||||
"RGB", Image.Resampling.BILINEAR, 3, 2, 2, 2, [0, 0, 0] * 7
|
"RGB", Image.Resampling.BILINEAR, 3, 2, 2, 2, (0, 0, 0) * 7
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(ValueError, match=r"size1D \* size2D \* size3D"):
|
with pytest.raises(ValueError, match=r"size1D \* size2D \* size3D"):
|
||||||
im.im.color_lut_3d(
|
im.im.color_lut_3d(
|
||||||
"RGB", Image.Resampling.BILINEAR, 3, 2, 2, 2, [0, 0, 0] * 9
|
"RGB", Image.Resampling.BILINEAR, 3, 2, 2, 2, (0, 0, 0) * 9
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
im.im.color_lut_3d(
|
im.im.color_lut_3d(
|
||||||
"RGB", Image.Resampling.BILINEAR, 3, 2, 2, 2, [0, 0, "0"] * 8
|
"RGB", Image.Resampling.BILINEAR, 3, 2, 2, 2, (0, 0, "0") * 8
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
|
@ -190,15 +190,15 @@ class TestColorLut3DCoreAPI:
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fast test with small cubes
|
# Fast test with small cubes
|
||||||
for size in [2, 3, 5, 7, 11, 16, 17]:
|
for size in (2, 3, 5, 7, 11, 16, 17):
|
||||||
assert_image_equal(
|
assert_image_equal(
|
||||||
im,
|
im,
|
||||||
im._new(
|
im._new(
|
||||||
|
@ -226,11 +226,11 @@ class TestColorLut3DCoreAPI:
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Red channel copied to alpha
|
# Red channel copied to alpha
|
||||||
|
@ -249,12 +249,12 @@ class TestColorLut3DCoreAPI:
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGBA",
|
"RGBA",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
g.transpose(Image.Transpose.ROTATE_270),
|
g.transpose(Image.Transpose.ROTATE_270),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert_image_equal(
|
assert_image_equal(
|
||||||
|
@ -272,11 +272,11 @@ class TestColorLut3DCoreAPI:
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Reverse channels by splitting and using table
|
# Reverse channels by splitting and using table
|
||||||
|
@ -284,36 +284,36 @@ class TestColorLut3DCoreAPI:
|
||||||
assert_image_equal(
|
assert_image_equal(
|
||||||
Image.merge('RGB', im.split()[::-1]),
|
Image.merge('RGB', im.split()[::-1]),
|
||||||
im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR,
|
im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR,
|
||||||
3, 2, 2, 2, [
|
3, 2, 2, 2, (
|
||||||
0, 0, 0, 0, 0, 1,
|
0, 0, 0, 0, 0, 1,
|
||||||
0, 1, 0, 0, 1, 1,
|
0, 1, 0, 0, 1, 1,
|
||||||
|
|
||||||
1, 0, 0, 1, 0, 1,
|
1, 0, 0, 1, 0, 1,
|
||||||
1, 1, 0, 1, 1, 1,
|
1, 1, 0, 1, 1, 1,
|
||||||
])))
|
))))
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
def test_overflow(self):
|
def test_overflow(self):
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
transformed = im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR,
|
transformed = im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR,
|
||||||
3, 2, 2, 2,
|
3, 2, 2, 2,
|
||||||
[
|
(
|
||||||
-1, -1, -1, 2, -1, -1,
|
-1, -1, -1, 2, -1, -1,
|
||||||
-1, 2, -1, 2, 2, -1,
|
-1, 2, -1, 2, 2, -1,
|
||||||
|
|
||||||
-1, -1, 2, 2, -1, 2,
|
-1, -1, 2, 2, -1, 2,
|
||||||
-1, 2, 2, 2, 2, 2,
|
-1, 2, 2, 2, 2, 2,
|
||||||
])).load()
|
))).load()
|
||||||
# fmt: on
|
# fmt: on
|
||||||
assert transformed[0, 0] == (0, 0, 255)
|
assert transformed[0, 0] == (0, 0, 255)
|
||||||
assert transformed[50, 50] == (0, 0, 255)
|
assert transformed[50, 50] == (0, 0, 255)
|
||||||
|
@ -327,13 +327,13 @@ class TestColorLut3DCoreAPI:
|
||||||
# fmt: off
|
# fmt: off
|
||||||
transformed = im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR,
|
transformed = im._new(im.im.color_lut_3d('RGB', Image.Resampling.BILINEAR,
|
||||||
3, 2, 2, 2,
|
3, 2, 2, 2,
|
||||||
[
|
(
|
||||||
-3, -3, -3, 5, -3, -3,
|
-3, -3, -3, 5, -3, -3,
|
||||||
-3, 5, -3, 5, 5, -3,
|
-3, 5, -3, 5, 5, -3,
|
||||||
|
|
||||||
-3, -3, 5, 5, -3, 5,
|
-3, -3, 5, 5, -3, 5,
|
||||||
-3, 5, 5, 5, 5, 5,
|
-3, 5, 5, 5, 5, 5,
|
||||||
])).load()
|
))).load()
|
||||||
# fmt: on
|
# fmt: on
|
||||||
assert transformed[0, 0] == (0, 0, 255)
|
assert transformed[0, 0] == (0, 0, 255)
|
||||||
assert transformed[50, 50] == (0, 0, 255)
|
assert transformed[50, 50] == (0, 0, 255)
|
||||||
|
@ -360,30 +360,38 @@ class TestColorLut3DFilter:
|
||||||
ImageFilter.Color3DLUT((11, 11, 66), [1])
|
ImageFilter.Color3DLUT((11, 11, 66), [1])
|
||||||
|
|
||||||
with pytest.raises(ValueError, match="table should have .+ items"):
|
with pytest.raises(ValueError, match="table should have .+ items"):
|
||||||
ImageFilter.Color3DLUT((3, 3, 3), [1, 1, 1])
|
ImageFilter.Color3DLUT((3, 3, 3), (1, 1, 1))
|
||||||
|
|
||||||
with pytest.raises(ValueError, match="table should have .+ items"):
|
with pytest.raises(ValueError, match="table should have .+ items"):
|
||||||
ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 2)
|
ImageFilter.Color3DLUT((3, 3, 3), [(1, 1, 1)] * 2)
|
||||||
|
|
||||||
with pytest.raises(ValueError, match="should have a length of 4"):
|
with pytest.raises(ValueError, match="should have a length of 4"):
|
||||||
ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 27, channels=4)
|
ImageFilter.Color3DLUT((3, 3, 3), [(1, 1, 1)] * 27, channels=4)
|
||||||
|
|
||||||
with pytest.raises(ValueError, match="should have a length of 3"):
|
with pytest.raises(ValueError, match="should have a length of 3"):
|
||||||
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8)
|
ImageFilter.Color3DLUT((2, 2, 2), [(1, 1)] * 8)
|
||||||
|
|
||||||
with pytest.raises(ValueError, match="Only 3 or 4 output"):
|
with pytest.raises(ValueError, match="Only 3 or 4 output"):
|
||||||
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8, channels=2)
|
ImageFilter.Color3DLUT((2, 2, 2), [(1, 1)] * 8, channels=2)
|
||||||
|
|
||||||
def test_convert_table(self):
|
def test_convert_table(self):
|
||||||
lut = ImageFilter.Color3DLUT(2, [0, 1, 2] * 8)
|
lut = ImageFilter.Color3DLUT(2, (0, 1, 2) * 8)
|
||||||
assert tuple(lut.size) == (2, 2, 2)
|
assert tuple(lut.size) == (2, 2, 2)
|
||||||
assert lut.name == "Color 3D LUT"
|
assert lut.name == "Color 3D LUT"
|
||||||
|
|
||||||
# fmt: off
|
lut = ImageFilter.Color3DLUT(
|
||||||
lut = ImageFilter.Color3DLUT((2, 2, 2), [
|
(2, 2, 2),
|
||||||
(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11),
|
(
|
||||||
(12, 13, 14), (15, 16, 17), (18, 19, 20), (21, 22, 23)])
|
(0, 1, 2),
|
||||||
# fmt: on
|
(3, 4, 5),
|
||||||
|
(6, 7, 8),
|
||||||
|
(9, 10, 11),
|
||||||
|
(12, 13, 14),
|
||||||
|
(15, 16, 17),
|
||||||
|
(18, 19, 20),
|
||||||
|
(21, 22, 23),
|
||||||
|
),
|
||||||
|
)
|
||||||
assert tuple(lut.size) == (2, 2, 2)
|
assert tuple(lut.size) == (2, 2, 2)
|
||||||
assert lut.table == list(range(24))
|
assert lut.table == list(range(24))
|
||||||
|
|
||||||
|
@ -429,11 +437,11 @@ class TestColorLut3DFilter:
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11), lambda r, g, b: (r, g, b))
|
||||||
|
@ -465,12 +473,12 @@ class TestColorLut3DFilter:
|
||||||
im.filter(lut)
|
im.filter(lut)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
lut = ImageFilter.Color3DLUT(2, [0, 1, 2] * 8)
|
lut = ImageFilter.Color3DLUT(2, (0, 1, 2) * 8)
|
||||||
assert repr(lut) == "<Color3DLUT from list size=2x2x2 channels=3>"
|
assert repr(lut) == "<Color3DLUT from list size=2x2x2 channels=3>"
|
||||||
|
|
||||||
lut = ImageFilter.Color3DLUT(
|
lut = ImageFilter.Color3DLUT(
|
||||||
(3, 4, 5),
|
(3, 4, 5),
|
||||||
array("f", [0, 0, 0, 0] * (3 * 4 * 5)),
|
array("f", (0, 0, 0, 0) * (3 * 4 * 5)),
|
||||||
channels=4,
|
channels=4,
|
||||||
target_mode="YCbCr",
|
target_mode="YCbCr",
|
||||||
_copy_table=False,
|
_copy_table=False,
|
||||||
|
@ -525,11 +533,11 @@ class TestGenerateColorLut3D:
|
||||||
g = Image.linear_gradient("L")
|
g = Image.linear_gradient("L")
|
||||||
im = Image.merge(
|
im = Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
g,
|
g,
|
||||||
g.transpose(Image.Transpose.ROTATE_90),
|
g.transpose(Image.Transpose.ROTATE_90),
|
||||||
g.transpose(Image.Transpose.ROTATE_180),
|
g.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
assert im == im.filter(lut)
|
assert im == im.filter(lut)
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class TestCoreMemory:
|
||||||
assert alignment > 0
|
assert alignment > 0
|
||||||
|
|
||||||
def test_set_alignment(self):
|
def test_set_alignment(self):
|
||||||
for i in [1, 2, 4, 8, 16, 32]:
|
for i in (1, 2, 4, 8, 16, 32):
|
||||||
Image.core.set_alignment(i)
|
Image.core.set_alignment(i)
|
||||||
alignment = Image.core.get_alignment()
|
alignment = Image.core.get_alignment()
|
||||||
assert alignment == i
|
assert alignment == i
|
||||||
|
@ -67,7 +67,7 @@ class TestCoreMemory:
|
||||||
assert block_size >= 4096
|
assert block_size >= 4096
|
||||||
|
|
||||||
def test_set_block_size(self):
|
def test_set_block_size(self):
|
||||||
for i in [4096, 2 * 4096, 3 * 4096]:
|
for i in (4096, 2 * 4096, 3 * 4096):
|
||||||
Image.core.set_block_size(i)
|
Image.core.set_block_size(i)
|
||||||
block_size = Image.core.get_block_size()
|
block_size = Image.core.get_block_size()
|
||||||
assert block_size == i
|
assert block_size == i
|
||||||
|
@ -100,7 +100,7 @@ class TestCoreMemory:
|
||||||
assert blocks_max >= 0
|
assert blocks_max >= 0
|
||||||
|
|
||||||
def test_set_blocks_max(self):
|
def test_set_blocks_max(self):
|
||||||
for i in [0, 1, 10]:
|
for i in (0, 1, 10):
|
||||||
Image.core.set_blocks_max(i)
|
Image.core.set_blocks_max(i)
|
||||||
blocks_max = Image.core.get_blocks_max()
|
blocks_max = Image.core.get_blocks_max()
|
||||||
assert blocks_max == i
|
assert blocks_max == i
|
||||||
|
|
|
@ -5,7 +5,7 @@ from PIL import _deprecate
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"version, expected",
|
"version, expected",
|
||||||
[
|
(
|
||||||
(
|
(
|
||||||
11,
|
11,
|
||||||
"Old thing is deprecated and will be removed in Pillow 11 "
|
"Old thing is deprecated and will be removed in Pillow 11 "
|
||||||
|
@ -16,7 +16,7 @@ from PIL import _deprecate
|
||||||
r"Old thing is deprecated and will be removed in a future version\. "
|
r"Old thing is deprecated and will be removed in a future version\. "
|
||||||
r"Use new thing instead\.",
|
r"Use new thing instead\.",
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_version(version, expected):
|
def test_version(version, expected):
|
||||||
with pytest.warns(DeprecationWarning, match=expected):
|
with pytest.warns(DeprecationWarning, match=expected):
|
||||||
|
@ -31,7 +31,7 @@ def test_unknown_version():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"deprecated, plural, expected",
|
"deprecated, plural, expected",
|
||||||
[
|
(
|
||||||
(
|
(
|
||||||
"Old thing",
|
"Old thing",
|
||||||
False,
|
False,
|
||||||
|
@ -42,7 +42,7 @@ def test_unknown_version():
|
||||||
True,
|
True,
|
||||||
r"Old things are deprecated and should be removed\.",
|
r"Old things are deprecated and should be removed\.",
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_old_version(deprecated, plural, expected):
|
def test_old_version(deprecated, plural, expected):
|
||||||
expected = r""
|
expected = r""
|
||||||
|
@ -69,10 +69,10 @@ def test_replacement_and_action():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"action",
|
"action",
|
||||||
[
|
(
|
||||||
"Upgrade to new thing",
|
"Upgrade to new thing",
|
||||||
"Upgrade to new thing.",
|
"Upgrade to new thing.",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_action(action):
|
def test_action(action):
|
||||||
expected = (
|
expected = (
|
||||||
|
|
|
@ -72,12 +72,12 @@ def test_libimagequant_version():
|
||||||
|
|
||||||
@pytest.mark.parametrize("feature", features.modules)
|
@pytest.mark.parametrize("feature", features.modules)
|
||||||
def test_check_modules(feature):
|
def test_check_modules(feature):
|
||||||
assert features.check_module(feature) in [True, False]
|
assert features.check_module(feature) in {True, False}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("feature", features.codecs)
|
@pytest.mark.parametrize("feature", features.codecs)
|
||||||
def test_check_codecs(feature):
|
def test_check_codecs(feature):
|
||||||
assert features.check_codec(feature) in [True, False]
|
assert features.check_codec(feature) in {True, False}
|
||||||
|
|
||||||
|
|
||||||
def test_check_warns_on_nonexistent():
|
def test_check_warns_on_nonexistent():
|
||||||
|
|
|
@ -117,12 +117,12 @@ def test_apng_dispose_op_previous_frame():
|
||||||
# red.save(
|
# red.save(
|
||||||
# "Tests/images/apng/dispose_op_previous_frame.png",
|
# "Tests/images/apng/dispose_op_previous_frame.png",
|
||||||
# save_all=True,
|
# save_all=True,
|
||||||
# append_images=[green, blue],
|
# append_images=(green, blue),
|
||||||
# disposal=[
|
# disposal=(
|
||||||
# PngImagePlugin.Disposal.OP_NONE,
|
# PngImagePlugin.Disposal.OP_NONE,
|
||||||
# PngImagePlugin.Disposal.OP_PREVIOUS,
|
# PngImagePlugin.Disposal.OP_PREVIOUS,
|
||||||
# PngImagePlugin.Disposal.OP_PREVIOUS
|
# PngImagePlugin.Disposal.OP_PREVIOUS
|
||||||
# ],
|
# ),
|
||||||
# )
|
# )
|
||||||
with Image.open("Tests/images/apng/dispose_op_previous_frame.png") as im:
|
with Image.open("Tests/images/apng/dispose_op_previous_frame.png") as im:
|
||||||
im.seek(im.n_frames - 1)
|
im.seek(im.n_frames - 1)
|
||||||
|
@ -381,7 +381,7 @@ def test_apng_save_split_fdat(tmp_path):
|
||||||
# data chunks)
|
# data chunks)
|
||||||
test_file = str(tmp_path / "temp.png")
|
test_file = str(tmp_path / "temp.png")
|
||||||
with Image.open("Tests/images/old-style-jpeg-compression.png") as im:
|
with Image.open("Tests/images/old-style-jpeg-compression.png") as im:
|
||||||
frames = [im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255))]
|
frames = (im.copy(), Image.new("RGBA", im.size, (255, 0, 0, 255)))
|
||||||
im.save(
|
im.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
|
@ -433,7 +433,7 @@ def test_apng_save_duration_loop(tmp_path):
|
||||||
# test removal of duplicated frames
|
# test removal of duplicated frames
|
||||||
frame = Image.new("RGBA", (128, 64), (255, 0, 0, 255))
|
frame = Image.new("RGBA", (128, 64), (255, 0, 0, 255))
|
||||||
frame.save(
|
frame.save(
|
||||||
test_file, save_all=True, append_images=[frame, frame], duration=[500, 100, 150]
|
test_file, save_all=True, append_images=(frame, frame), duration=(500, 100, 150)
|
||||||
)
|
)
|
||||||
with Image.open(test_file) as im:
|
with Image.open(test_file) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
@ -458,7 +458,7 @@ def test_apng_save_disposal(tmp_path):
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[green, transparent],
|
append_images=(green, transparent),
|
||||||
disposal=PngImagePlugin.Disposal.OP_NONE,
|
disposal=PngImagePlugin.Disposal.OP_NONE,
|
||||||
blend=PngImagePlugin.Blend.OP_OVER,
|
blend=PngImagePlugin.Blend.OP_OVER,
|
||||||
)
|
)
|
||||||
|
@ -468,15 +468,15 @@ def test_apng_save_disposal(tmp_path):
|
||||||
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
||||||
|
|
||||||
# test OP_BACKGROUND
|
# test OP_BACKGROUND
|
||||||
disposal = [
|
disposal = (
|
||||||
PngImagePlugin.Disposal.OP_NONE,
|
PngImagePlugin.Disposal.OP_NONE,
|
||||||
PngImagePlugin.Disposal.OP_BACKGROUND,
|
PngImagePlugin.Disposal.OP_BACKGROUND,
|
||||||
PngImagePlugin.Disposal.OP_NONE,
|
PngImagePlugin.Disposal.OP_NONE,
|
||||||
]
|
)
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[red, transparent],
|
append_images=(red, transparent),
|
||||||
disposal=disposal,
|
disposal=disposal,
|
||||||
blend=PngImagePlugin.Blend.OP_OVER,
|
blend=PngImagePlugin.Blend.OP_OVER,
|
||||||
)
|
)
|
||||||
|
@ -485,10 +485,10 @@ def test_apng_save_disposal(tmp_path):
|
||||||
assert im.getpixel((0, 0)) == (0, 0, 0, 0)
|
assert im.getpixel((0, 0)) == (0, 0, 0, 0)
|
||||||
assert im.getpixel((64, 32)) == (0, 0, 0, 0)
|
assert im.getpixel((64, 32)) == (0, 0, 0, 0)
|
||||||
|
|
||||||
disposal = [
|
disposal = (
|
||||||
PngImagePlugin.Disposal.OP_NONE,
|
PngImagePlugin.Disposal.OP_NONE,
|
||||||
PngImagePlugin.Disposal.OP_BACKGROUND,
|
PngImagePlugin.Disposal.OP_BACKGROUND,
|
||||||
]
|
)
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
|
@ -502,15 +502,15 @@ def test_apng_save_disposal(tmp_path):
|
||||||
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
||||||
|
|
||||||
# test OP_PREVIOUS
|
# test OP_PREVIOUS
|
||||||
disposal = [
|
disposal = (
|
||||||
PngImagePlugin.Disposal.OP_NONE,
|
PngImagePlugin.Disposal.OP_NONE,
|
||||||
PngImagePlugin.Disposal.OP_PREVIOUS,
|
PngImagePlugin.Disposal.OP_PREVIOUS,
|
||||||
PngImagePlugin.Disposal.OP_NONE,
|
PngImagePlugin.Disposal.OP_NONE,
|
||||||
]
|
)
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[green, red, transparent],
|
append_images=(green, red, transparent),
|
||||||
default_image=True,
|
default_image=True,
|
||||||
disposal=disposal,
|
disposal=disposal,
|
||||||
blend=PngImagePlugin.Blend.OP_OVER,
|
blend=PngImagePlugin.Blend.OP_OVER,
|
||||||
|
@ -520,10 +520,10 @@ def test_apng_save_disposal(tmp_path):
|
||||||
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
||||||
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
||||||
|
|
||||||
disposal = [
|
disposal = (
|
||||||
PngImagePlugin.Disposal.OP_NONE,
|
PngImagePlugin.Disposal.OP_NONE,
|
||||||
PngImagePlugin.Disposal.OP_PREVIOUS,
|
PngImagePlugin.Disposal.OP_PREVIOUS,
|
||||||
]
|
)
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
|
@ -559,7 +559,7 @@ def test_apng_save_disposal_previous(tmp_path):
|
||||||
blue.save(
|
blue.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[red, green],
|
append_images=(red, green),
|
||||||
disposal=PngImagePlugin.Disposal.OP_PREVIOUS,
|
disposal=PngImagePlugin.Disposal.OP_PREVIOUS,
|
||||||
)
|
)
|
||||||
with Image.open(test_file) as im:
|
with Image.open(test_file) as im:
|
||||||
|
@ -578,14 +578,14 @@ def test_apng_save_blend(tmp_path):
|
||||||
transparent = Image.new("RGBA", size, (0, 0, 0, 0))
|
transparent = Image.new("RGBA", size, (0, 0, 0, 0))
|
||||||
|
|
||||||
# test OP_SOURCE on solid color
|
# test OP_SOURCE on solid color
|
||||||
blend = [
|
blend = (
|
||||||
PngImagePlugin.Blend.OP_OVER,
|
PngImagePlugin.Blend.OP_OVER,
|
||||||
PngImagePlugin.Blend.OP_SOURCE,
|
PngImagePlugin.Blend.OP_SOURCE,
|
||||||
]
|
)
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[red, green],
|
append_images=(red, green),
|
||||||
default_image=True,
|
default_image=True,
|
||||||
disposal=PngImagePlugin.Disposal.OP_NONE,
|
disposal=PngImagePlugin.Disposal.OP_NONE,
|
||||||
blend=blend,
|
blend=blend,
|
||||||
|
@ -596,14 +596,14 @@ def test_apng_save_blend(tmp_path):
|
||||||
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
|
||||||
|
|
||||||
# test OP_SOURCE on transparent color
|
# test OP_SOURCE on transparent color
|
||||||
blend = [
|
blend = (
|
||||||
PngImagePlugin.Blend.OP_OVER,
|
PngImagePlugin.Blend.OP_OVER,
|
||||||
PngImagePlugin.Blend.OP_SOURCE,
|
PngImagePlugin.Blend.OP_SOURCE,
|
||||||
]
|
)
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[red, transparent],
|
append_images=(red, transparent),
|
||||||
default_image=True,
|
default_image=True,
|
||||||
disposal=PngImagePlugin.Disposal.OP_NONE,
|
disposal=PngImagePlugin.Disposal.OP_NONE,
|
||||||
blend=blend,
|
blend=blend,
|
||||||
|
@ -617,7 +617,7 @@ def test_apng_save_blend(tmp_path):
|
||||||
red.save(
|
red.save(
|
||||||
test_file,
|
test_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[green, transparent],
|
append_images=(green, transparent),
|
||||||
default_image=True,
|
default_image=True,
|
||||||
disposal=PngImagePlugin.Disposal.OP_NONE,
|
disposal=PngImagePlugin.Disposal.OP_NONE,
|
||||||
blend=PngImagePlugin.Blend.OP_OVER,
|
blend=PngImagePlugin.Blend.OP_OVER,
|
||||||
|
@ -632,7 +632,7 @@ def test_apng_save_blend(tmp_path):
|
||||||
|
|
||||||
# test info blend
|
# test info blend
|
||||||
red.info["blend"] = PngImagePlugin.Blend.OP_OVER
|
red.info["blend"] = PngImagePlugin.Blend.OP_OVER
|
||||||
red.save(test_file, save_all=True, append_images=[green, transparent])
|
red.save(test_file, save_all=True, append_images=(green, transparent))
|
||||||
with Image.open(test_file) as im:
|
with Image.open(test_file) as im:
|
||||||
im.seek(2)
|
im.seek(2)
|
||||||
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
||||||
|
|
|
@ -57,7 +57,7 @@ def test_save(tmp_path):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
(
|
||||||
"Tests/images/timeout-060745d3f534ad6e4128c51d336ea5489182c69d.blp",
|
"Tests/images/timeout-060745d3f534ad6e4128c51d336ea5489182c69d.blp",
|
||||||
"Tests/images/timeout-31c8f86233ea728339c6e586be7af661a09b5b98.blp",
|
"Tests/images/timeout-31c8f86233ea728339c6e586be7af661a09b5b98.blp",
|
||||||
"Tests/images/timeout-60d8b7c8469d59fc9ffff6b3a3dc0faeae6ea8ee.blp",
|
"Tests/images/timeout-60d8b7c8469d59fc9ffff6b3a3dc0faeae6ea8ee.blp",
|
||||||
|
@ -65,7 +65,7 @@ def test_save(tmp_path):
|
||||||
"Tests/images/timeout-bba4f2e026b5786529370e5dfe9a11b1bf991f07.blp",
|
"Tests/images/timeout-bba4f2e026b5786529370e5dfe9a11b1bf991f07.blp",
|
||||||
"Tests/images/timeout-d6ec061c4afdef39d3edf6da8927240bb07fe9b7.blp",
|
"Tests/images/timeout-d6ec061c4afdef39d3edf6da8927240bb07fe9b7.blp",
|
||||||
"Tests/images/timeout-ef9112a065e7183fa7faa2e18929b03e44ee16bf.blp",
|
"Tests/images/timeout-ef9112a065e7183fa7faa2e18929b03e44ee16bf.blp",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_crashes(test_file):
|
def test_crashes(test_file):
|
||||||
with open(test_file, "rb") as f:
|
with open(test_file, "rb") as f:
|
||||||
|
|
|
@ -304,12 +304,12 @@ def test_save_unsupported_mode(tmp_path):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("mode", "test_file"),
|
("mode", "test_file"),
|
||||||
[
|
(
|
||||||
("L", "Tests/images/linear_gradient.png"),
|
("L", "Tests/images/linear_gradient.png"),
|
||||||
("LA", "Tests/images/uncompressed_la.png"),
|
("LA", "Tests/images/uncompressed_la.png"),
|
||||||
("RGB", "Tests/images/hopper.png"),
|
("RGB", "Tests/images/hopper.png"),
|
||||||
("RGBA", "Tests/images/pil123rgba.png"),
|
("RGBA", "Tests/images/pil123rgba.png"),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_save(mode, test_file, tmp_path):
|
def test_save(mode, test_file, tmp_path):
|
||||||
out = str(tmp_path / "temp.dds")
|
out = str(tmp_path / "temp.dds")
|
||||||
|
|
|
@ -314,8 +314,8 @@ def test_read_binary_preview():
|
||||||
def test_readline_psfile(tmp_path):
|
def test_readline_psfile(tmp_path):
|
||||||
# check all the freaking line endings possible from the spec
|
# check all the freaking line endings possible from the spec
|
||||||
# test_string = u'something\r\nelse\n\rbaz\rbif\n'
|
# test_string = u'something\r\nelse\n\rbaz\rbif\n'
|
||||||
line_endings = ["\r\n", "\n", "\n\r", "\r"]
|
line_endings = ("\r\n", "\n", "\n\r", "\r")
|
||||||
strings = ["something", "else", "baz", "bif"]
|
strings = ("something", "else", "baz", "bif")
|
||||||
|
|
||||||
def _test_readline(t, ending):
|
def _test_readline(t, ending):
|
||||||
ending = "Failure with line ending: %s" % (
|
ending = "Failure with line ending: %s" % (
|
||||||
|
|
|
@ -139,10 +139,10 @@ def test_seek():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
(
|
||||||
"Tests/images/timeout-9139147ce93e20eb14088fe238e541443ffd64b3.fli",
|
"Tests/images/timeout-9139147ce93e20eb14088fe238e541443ffd64b3.fli",
|
||||||
"Tests/images/timeout-bff0a9dc7243a8e6ede2408d2ffa6a9964698b87.fli",
|
"Tests/images/timeout-bff0a9dc7243a8e6ede2408d2ffa6a9964698b87.fli",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
@pytest.mark.timeout(timeout=3)
|
@pytest.mark.timeout(timeout=3)
|
||||||
def test_timeouts(test_file):
|
def test_timeouts(test_file):
|
||||||
|
@ -154,9 +154,7 @@ def test_timeouts(test_file):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
("Tests/images/crash-5762152299364352.fli",),
|
||||||
"Tests/images/crash-5762152299364352.fli",
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
def test_crash(test_file):
|
def test_crash(test_file):
|
||||||
with open(test_file, "rb") as f:
|
with open(test_file, "rb") as f:
|
||||||
|
|
|
@ -279,13 +279,14 @@ def test_loading_multiple_palettes(path, mode):
|
||||||
|
|
||||||
|
|
||||||
def test_headers_saving_for_animated_gifs(tmp_path):
|
def test_headers_saving_for_animated_gifs(tmp_path):
|
||||||
important_headers = ["background", "version", "duration", "loop"]
|
important_headers = ("background", "version", "duration", "loop")
|
||||||
|
|
||||||
# Multiframe image
|
# Multiframe image
|
||||||
with Image.open("Tests/images/dispose_bgnd.gif") as im:
|
with Image.open("Tests/images/dispose_bgnd.gif") as im:
|
||||||
info = im.info.copy()
|
info = im.info.copy()
|
||||||
|
|
||||||
out = str(tmp_path / "temp.gif")
|
out = str(tmp_path / "temp.gif")
|
||||||
im.save(out, save_all=True)
|
im.save(out, save_all=True)
|
||||||
|
|
||||||
with Image.open(out) as reread:
|
with Image.open(out) as reread:
|
||||||
for header in important_headers:
|
for header in important_headers:
|
||||||
assert info[header] == reread.info[header]
|
assert info[header] == reread.info[header]
|
||||||
|
@ -459,10 +460,9 @@ def test_dispose_none_load_end():
|
||||||
# im = Image.open("transparent.gif")
|
# im = Image.open("transparent.gif")
|
||||||
# im_rotated = im.rotate(180)
|
# im_rotated = im.rotate(180)
|
||||||
# im.save("dispose_none_load_end.gif",
|
# im.save("dispose_none_load_end.gif",
|
||||||
# save_all=True, append_images=[im_rotated], disposal=[1,2])
|
# save_all=True, append_images=[im_rotated], disposal=(1, 2))
|
||||||
with Image.open("Tests/images/dispose_none_load_end.gif") as img:
|
with Image.open("Tests/images/dispose_none_load_end.gif") as img:
|
||||||
img.seek(1)
|
img.seek(1)
|
||||||
|
|
||||||
assert_image_equal_tofile(img, "Tests/images/dispose_none_load_end_second.png")
|
assert_image_equal_tofile(img, "Tests/images/dispose_none_load_end_second.png")
|
||||||
|
|
||||||
|
|
||||||
|
@ -578,7 +578,7 @@ def test_dispose2_palette(tmp_path):
|
||||||
out = str(tmp_path / "temp.gif")
|
out = str(tmp_path / "temp.gif")
|
||||||
|
|
||||||
# Four colors: white, grey, black, red
|
# Four colors: white, grey, black, red
|
||||||
circles = [(255, 255, 255), (153, 153, 153), (0, 0, 0), (255, 0, 0)]
|
circles = ((255, 255, 255), (153, 153, 153), (0, 0, 0), (255, 0, 0))
|
||||||
|
|
||||||
im_list = []
|
im_list = []
|
||||||
for circle in circles:
|
for circle in circles:
|
||||||
|
@ -587,7 +587,7 @@ def test_dispose2_palette(tmp_path):
|
||||||
|
|
||||||
# Circle in center of each frame
|
# Circle in center of each frame
|
||||||
d = ImageDraw.Draw(img)
|
d = ImageDraw.Draw(img)
|
||||||
d.ellipse([(40, 40), (60, 60)], fill=circle)
|
d.ellipse(((40, 40), (60, 60)), fill=circle)
|
||||||
|
|
||||||
im_list.append(img)
|
im_list.append(img)
|
||||||
|
|
||||||
|
@ -609,12 +609,12 @@ def test_dispose2_diff(tmp_path):
|
||||||
out = str(tmp_path / "temp.gif")
|
out = str(tmp_path / "temp.gif")
|
||||||
|
|
||||||
# 4 frames: red/blue, red/red, blue/blue, red/blue
|
# 4 frames: red/blue, red/red, blue/blue, red/blue
|
||||||
circles = [
|
circles = (
|
||||||
((255, 0, 0, 255), (0, 0, 255, 255)),
|
((255, 0, 0, 255), (0, 0, 255, 255)),
|
||||||
((255, 0, 0, 255), (255, 0, 0, 255)),
|
((255, 0, 0, 255), (255, 0, 0, 255)),
|
||||||
((0, 0, 255, 255), (0, 0, 255, 255)),
|
((0, 0, 255, 255), (0, 0, 255, 255)),
|
||||||
((255, 0, 0, 255), (0, 0, 255, 255)),
|
((255, 0, 0, 255), (0, 0, 255, 255)),
|
||||||
]
|
)
|
||||||
|
|
||||||
im_list = []
|
im_list = []
|
||||||
for i in range(len(circles)):
|
for i in range(len(circles)):
|
||||||
|
@ -623,8 +623,8 @@ def test_dispose2_diff(tmp_path):
|
||||||
|
|
||||||
# Two circles per frame
|
# Two circles per frame
|
||||||
d = ImageDraw.Draw(img)
|
d = ImageDraw.Draw(img)
|
||||||
d.ellipse([(0, 30), (40, 70)], fill=circles[i][0])
|
d.ellipse(((0, 30), (40, 70)), fill=circles[i][0])
|
||||||
d.ellipse([(60, 30), (100, 70)], fill=circles[i][1])
|
d.ellipse(((60, 30), (100, 70)), fill=circles[i][1])
|
||||||
|
|
||||||
im_list.append(img)
|
im_list.append(img)
|
||||||
|
|
||||||
|
@ -654,14 +654,14 @@ def test_dispose2_background(tmp_path):
|
||||||
|
|
||||||
im = Image.new("P", (100, 100))
|
im = Image.new("P", (100, 100))
|
||||||
d = ImageDraw.Draw(im)
|
d = ImageDraw.Draw(im)
|
||||||
d.rectangle([(50, 0), (100, 100)], fill="#f00")
|
d.rectangle(((50, 0), (100, 100)), fill="#f00")
|
||||||
d.rectangle([(0, 0), (50, 100)], fill="#0f0")
|
d.rectangle(((0, 0), (50, 100)), fill="#0f0")
|
||||||
im_list.append(im)
|
im_list.append(im)
|
||||||
|
|
||||||
im = Image.new("P", (100, 100))
|
im = Image.new("P", (100, 100))
|
||||||
d = ImageDraw.Draw(im)
|
d = ImageDraw.Draw(im)
|
||||||
d.rectangle([(0, 0), (100, 50)], fill="#f00")
|
d.rectangle(((0, 0), (100, 50)), fill="#f00")
|
||||||
d.rectangle([(0, 50), (100, 100)], fill="#0f0")
|
d.rectangle(((0, 50), (100, 100)), fill="#0f0")
|
||||||
im_list.append(im)
|
im_list.append(im)
|
||||||
|
|
||||||
im_list[0].save(
|
im_list[0].save(
|
||||||
|
@ -1153,7 +1153,7 @@ def test_palette_save_duplicate_entries(tmp_path):
|
||||||
im.putpalette((0, 0, 0, 0, 0, 0))
|
im.putpalette((0, 0, 0, 0, 0, 0))
|
||||||
|
|
||||||
out = str(tmp_path / "temp.gif")
|
out = str(tmp_path / "temp.gif")
|
||||||
im.save(out, palette=[0, 0, 0, 0, 0, 0, 1, 1, 1])
|
im.save(out, palette=(0, 0, 0, 0, 0, 0, 1, 1, 1))
|
||||||
|
|
||||||
with Image.open(out) as reloaded:
|
with Image.open(out) as reloaded:
|
||||||
assert reloaded.convert("RGB").getpixel((0, 1)) == (0, 0, 0)
|
assert reloaded.convert("RGB").getpixel((0, 1)) == (0, 0, 0)
|
||||||
|
|
|
@ -44,7 +44,7 @@ def test_invalid_file():
|
||||||
def test_save_to_bytes():
|
def test_save_to_bytes():
|
||||||
output = io.BytesIO()
|
output = io.BytesIO()
|
||||||
im = hopper()
|
im = hopper()
|
||||||
im.save(output, "ico", sizes=[(32, 32), (64, 64)])
|
im.save(output, "ico", sizes=((32, 32), (64, 64)))
|
||||||
|
|
||||||
# The default image
|
# The default image
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
@ -135,7 +135,7 @@ def test_different_bit_depths(tmp_path):
|
||||||
def test_save_to_bytes_bmp(mode):
|
def test_save_to_bytes_bmp(mode):
|
||||||
output = io.BytesIO()
|
output = io.BytesIO()
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
im.save(output, "ico", bitmap_format="bmp", sizes=[(32, 32), (64, 64)])
|
im.save(output, "ico", bitmap_format="bmp", sizes=((32, 32), (64, 64)))
|
||||||
|
|
||||||
# The default image
|
# The default image
|
||||||
output.seek(0)
|
output.seek(0)
|
||||||
|
@ -200,7 +200,7 @@ def test_save_append_images(tmp_path):
|
||||||
im = hopper("RGBA")
|
im = hopper("RGBA")
|
||||||
provided_im = Image.new("RGBA", (32, 32), (255, 0, 0))
|
provided_im = Image.new("RGBA", (32, 32), (255, 0, 0))
|
||||||
outfile = str(tmp_path / "temp_saved_multi_icon.ico")
|
outfile = str(tmp_path / "temp_saved_multi_icon.ico")
|
||||||
im.save(outfile, sizes=[(32, 32), (128, 128)], append_images=[provided_im])
|
im.save(outfile, sizes=((32, 32), (128, 128)), append_images=[provided_im])
|
||||||
|
|
||||||
with Image.open(outfile) as reread:
|
with Image.open(outfile) as reread:
|
||||||
assert_image_equal(reread, hopper("RGBA"))
|
assert_image_equal(reread, hopper("RGBA"))
|
||||||
|
|
|
@ -143,7 +143,7 @@ class TestFileJpeg:
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_image_path",
|
"test_image_path",
|
||||||
[TEST_FILE, "Tests/images/pil_sample_cmyk.jpg"],
|
(TEST_FILE, "Tests/images/pil_sample_cmyk.jpg"),
|
||||||
)
|
)
|
||||||
def test_dpi(self, test_image_path):
|
def test_dpi(self, test_image_path):
|
||||||
def test(xdpi, ydpi=None):
|
def test(xdpi, ydpi=None):
|
||||||
|
@ -559,6 +559,7 @@ class TestFileJpeg:
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
# list of qtable lists
|
# list of qtable lists
|
||||||
assert_image_similar(
|
assert_image_similar(
|
||||||
im,
|
im,
|
||||||
|
|
|
@ -125,7 +125,7 @@ def test_irreversible_rt():
|
||||||
|
|
||||||
|
|
||||||
def test_prog_qual_rt():
|
def test_prog_qual_rt():
|
||||||
im = roundtrip(test_card, quality_layers=[60, 40, 20], progression="LRCP")
|
im = roundtrip(test_card, quality_layers=(60, 40, 20), progression="LRCP")
|
||||||
assert_image_similar(im, test_card, 2.0)
|
assert_image_similar(im, test_card, 2.0)
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,17 +192,17 @@ def test_header_errors():
|
||||||
|
|
||||||
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")
|
||||||
for quality_layers in [[100, 50, 10], (100, 50, 10), None]:
|
for quality_layers in ([100, 50, 10], (100, 50, 10), None):
|
||||||
test_card.save(outfile, quality_layers=quality_layers)
|
test_card.save(outfile, quality_layers=quality_layers)
|
||||||
|
|
||||||
for quality_layers in ["quality_layers", ("100", "50", "10")]:
|
for quality_layers in ("quality_layers", ("100", "50", "10")):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
test_card.save(outfile, quality_layers=quality_layers)
|
test_card.save(outfile, quality_layers=quality_layers)
|
||||||
|
|
||||||
|
|
||||||
def test_layers():
|
def test_layers():
|
||||||
out = BytesIO()
|
out = BytesIO()
|
||||||
test_card.save(out, "JPEG2000", quality_layers=[100, 50, 10], progression="LRCP")
|
test_card.save(out, "JPEG2000", quality_layers=(100, 50, 10), progression="LRCP")
|
||||||
out.seek(0)
|
out.seek(0)
|
||||||
|
|
||||||
with Image.open(out) as im:
|
with Image.open(out) as im:
|
||||||
|
@ -392,12 +392,12 @@ def test_save_comment():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
(
|
||||||
"Tests/images/crash-4fb027452e6988530aa5dabee76eecacb3b79f8a.j2k",
|
"Tests/images/crash-4fb027452e6988530aa5dabee76eecacb3b79f8a.j2k",
|
||||||
"Tests/images/crash-7d4c83eb92150fb8f1653a697703ae06ae7c4998.j2k",
|
"Tests/images/crash-7d4c83eb92150fb8f1653a697703ae06ae7c4998.j2k",
|
||||||
"Tests/images/crash-ccca68ff40171fdae983d924e127a721cab2bd50.j2k",
|
"Tests/images/crash-ccca68ff40171fdae983d924e127a721cab2bd50.j2k",
|
||||||
"Tests/images/crash-d2c93af851d3ab9a19e34503626368b2ecde9c03.j2k",
|
"Tests/images/crash-d2c93af851d3ab9a19e34503626368b2ecde9c03.j2k",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_crashes(test_file):
|
def test_crashes(test_file):
|
||||||
with open(test_file, "rb") as f:
|
with open(test_file, "rb") as f:
|
||||||
|
|
|
@ -150,12 +150,12 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
|
|
||||||
# PhotometricInterpretation is set from SAVE_INFO,
|
# PhotometricInterpretation is set from SAVE_INFO,
|
||||||
# not the original image.
|
# not the original image.
|
||||||
ignored = [
|
ignored = {
|
||||||
"StripByteCounts",
|
"StripByteCounts",
|
||||||
"RowsPerStrip",
|
"RowsPerStrip",
|
||||||
"PageNumber",
|
"PageNumber",
|
||||||
"PhotometricInterpretation",
|
"PhotometricInterpretation",
|
||||||
]
|
}
|
||||||
|
|
||||||
with Image.open(f) as loaded:
|
with Image.open(f) as loaded:
|
||||||
if legacy_api:
|
if legacy_api:
|
||||||
|
@ -177,7 +177,7 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
assert val == value, f"{tag} didn't roundtrip"
|
assert val == value, f"{tag} didn't roundtrip"
|
||||||
|
|
||||||
# https://github.com/python-pillow/Pillow/issues/1561
|
# https://github.com/python-pillow/Pillow/issues/1561
|
||||||
requested_fields = ["StripByteCounts", "RowsPerStrip", "StripOffsets"]
|
requested_fields = ("StripByteCounts", "RowsPerStrip", "StripOffsets")
|
||||||
for field in requested_fields:
|
for field in requested_fields:
|
||||||
assert field in reloaded, f"{field} not in metadata"
|
assert field in reloaded, f"{field} not in metadata"
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
custom = {
|
custom = {
|
||||||
37000 + k: v
|
37000 + k: v
|
||||||
for k, v in enumerate(
|
for k, v in enumerate(
|
||||||
[
|
(
|
||||||
tc(4, TiffTags.SHORT, True),
|
tc(4, TiffTags.SHORT, True),
|
||||||
tc(123456789, TiffTags.LONG, True),
|
tc(123456789, TiffTags.LONG, True),
|
||||||
tc(-4, TiffTags.SIGNED_BYTE, False),
|
tc(-4, TiffTags.SIGNED_BYTE, False),
|
||||||
|
@ -270,7 +270,7 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
# compatibility
|
# compatibility
|
||||||
tc(bytes([4]), TiffTags.BYTE, True),
|
tc(bytes([4]), TiffTags.BYTE, True),
|
||||||
tc(bytes((4, 9, 10)), TiffTags.BYTE, True),
|
tc(bytes((4, 9, 10)), TiffTags.BYTE, True),
|
||||||
]
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from .helper import (
|
||||||
skip_unless_feature,
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"]
|
test_files = ("Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo")
|
||||||
|
|
||||||
pytestmark = skip_unless_feature("jpg")
|
pytestmark = skip_unless_feature("jpg")
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ class TestFilePng:
|
||||||
assert im.format == "PNG"
|
assert im.format == "PNG"
|
||||||
assert im.get_format_mimetype() == "image/png"
|
assert im.get_format_mimetype() == "image/png"
|
||||||
|
|
||||||
for mode in ["1", "L", "P", "RGB", "I", "I;16"]:
|
for mode in ("1", "L", "P", "RGB", "I", "I;16"):
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
im.save(test_file)
|
im.save(test_file)
|
||||||
with Image.open(test_file) as reloaded:
|
with Image.open(test_file) as reloaded:
|
||||||
|
|
|
@ -56,7 +56,7 @@ def test_n_frames():
|
||||||
assert im.n_frames == 1
|
assert im.n_frames == 1
|
||||||
assert not im.is_animated
|
assert not im.is_animated
|
||||||
|
|
||||||
for path in [test_file, "Tests/images/negative_layer_count.psd"]:
|
for path in (test_file, "Tests/images/negative_layer_count.psd"):
|
||||||
with Image.open(path) as im:
|
with Image.open(path) as im:
|
||||||
assert im.n_frames == 2
|
assert im.n_frames == 2
|
||||||
assert im.is_animated
|
assert im.is_animated
|
||||||
|
@ -137,7 +137,7 @@ def test_combined_larger_than_size():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file,raises",
|
"test_file,raises",
|
||||||
[
|
(
|
||||||
(
|
(
|
||||||
"Tests/images/timeout-1ee28a249896e05b83840ae8140622de8e648ba9.psd",
|
"Tests/images/timeout-1ee28a249896e05b83840ae8140622de8e648ba9.psd",
|
||||||
Image.UnidentifiedImageError,
|
Image.UnidentifiedImageError,
|
||||||
|
@ -148,7 +148,7 @@ def test_combined_larger_than_size():
|
||||||
),
|
),
|
||||||
("Tests/images/timeout-c8efc3fded6426986ba867a399791bae544f59bc.psd", OSError),
|
("Tests/images/timeout-c8efc3fded6426986ba867a399791bae544f59bc.psd", OSError),
|
||||||
("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError),
|
("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_crashes(test_file, raises):
|
def test_crashes(test_file, raises):
|
||||||
with open(test_file, "rb") as f:
|
with open(test_file, "rb") as f:
|
||||||
|
|
|
@ -96,7 +96,7 @@ def test_n_frames():
|
||||||
def test_load_image_series():
|
def test_load_image_series():
|
||||||
# Arrange
|
# Arrange
|
||||||
not_spider_file = "Tests/images/hopper.ppm"
|
not_spider_file = "Tests/images/hopper.ppm"
|
||||||
file_list = [TEST_FILE, not_spider_file, "path/not_found.ext"]
|
file_list = (TEST_FILE, not_spider_file, "path/not_found.ext")
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
img_list = SpiderImagePlugin.loadImageSeries(file_list)
|
img_list = SpiderImagePlugin.loadImageSeries(file_list)
|
||||||
|
|
|
@ -144,7 +144,7 @@ class TestFileTiff:
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"resolution_unit, dpi",
|
"resolution_unit, dpi",
|
||||||
[(None, 72.8), (2, 72.8), (3, 184.912)],
|
((None, 72.8), (2, 72.8), (3, 184.912)),
|
||||||
)
|
)
|
||||||
def test_load_float_dpi(self, resolution_unit, dpi):
|
def test_load_float_dpi(self, resolution_unit, dpi):
|
||||||
with Image.open(
|
with Image.open(
|
||||||
|
@ -450,7 +450,7 @@ class TestFileTiff:
|
||||||
assert exif[271] == "FLIR"
|
assert exif[271] == "FLIR"
|
||||||
|
|
||||||
gps = exif.get_ifd(0x8825)
|
gps = exif.get_ifd(0x8825)
|
||||||
assert list(gps.keys()) == [0, 1, 2, 3, 4, 5, 6, 18]
|
assert tuple(gps.keys()) == (0, 1, 2, 3, 4, 5, 6, 18)
|
||||||
assert gps[0] == b"\x03\x02\x00\x00"
|
assert gps[0] == b"\x03\x02\x00\x00"
|
||||||
assert gps[18] == "WGS-84"
|
assert gps[18] == "WGS-84"
|
||||||
|
|
||||||
|
@ -663,7 +663,7 @@ class TestFileTiff:
|
||||||
# Test appending images
|
# Test appending images
|
||||||
mp = BytesIO()
|
mp = BytesIO()
|
||||||
im = Image.new("RGB", (100, 100), "#f00")
|
im = Image.new("RGB", (100, 100), "#f00")
|
||||||
ims = [Image.new("RGB", (100, 100), color) for color in ["#0f0", "#00f"]]
|
ims = [Image.new("RGB", (100, 100), color) for color in ("#0f0", "#00f")]
|
||||||
im.copy().save(mp, format="TIFF", save_all=True, append_images=ims)
|
im.copy().save(mp, format="TIFF", save_all=True, append_images=ims)
|
||||||
|
|
||||||
mp.seek(0, os.SEEK_SET)
|
mp.seek(0, os.SEEK_SET)
|
||||||
|
@ -738,7 +738,7 @@ class TestFileTiff:
|
||||||
|
|
||||||
def test_get_photoshop_blocks(self):
|
def test_get_photoshop_blocks(self):
|
||||||
with Image.open("Tests/images/lab.tif") as im:
|
with Image.open("Tests/images/lab.tif") as im:
|
||||||
assert list(im.get_photoshop_blocks().keys()) == [
|
assert tuple(im.get_photoshop_blocks().keys()) == (
|
||||||
1061,
|
1061,
|
||||||
1002,
|
1002,
|
||||||
1005,
|
1005,
|
||||||
|
@ -760,7 +760,7 @@ class TestFileTiff:
|
||||||
1057,
|
1057,
|
||||||
4000,
|
4000,
|
||||||
4001,
|
4001,
|
||||||
]
|
)
|
||||||
|
|
||||||
def test_close_on_load_exclusive(self, tmp_path):
|
def test_close_on_load_exclusive(self, tmp_path):
|
||||||
# similar to test_fd_leak, but runs on unixlike os
|
# similar to test_fd_leak, but runs on unixlike os
|
||||||
|
|
|
@ -129,7 +129,7 @@ def test_write_metadata(tmp_path):
|
||||||
with Image.open(f) as loaded:
|
with Image.open(f) as loaded:
|
||||||
reloaded = loaded.tag_v2.named()
|
reloaded = loaded.tag_v2.named()
|
||||||
|
|
||||||
ignored = ["StripByteCounts", "RowsPerStrip", "PageNumber", "StripOffsets"]
|
ignored = {"StripByteCounts", "RowsPerStrip", "PageNumber", "StripOffsets"}
|
||||||
|
|
||||||
for tag, value in reloaded.items():
|
for tag, value in reloaded.items():
|
||||||
if tag in ignored:
|
if tag in ignored:
|
||||||
|
|
|
@ -109,14 +109,14 @@ def test_timestamp_and_duration(tmp_path):
|
||||||
timestamps and durations are correct.
|
timestamps and durations are correct.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
durations = [0, 10, 20, 30, 40]
|
durations = (0, 10, 20, 30, 40)
|
||||||
temp_file = str(tmp_path / "temp.webp")
|
temp_file = str(tmp_path / "temp.webp")
|
||||||
with Image.open("Tests/images/anim_frame1.webp") as frame1:
|
with Image.open("Tests/images/anim_frame1.webp") as frame1:
|
||||||
with Image.open("Tests/images/anim_frame2.webp") as frame2:
|
with Image.open("Tests/images/anim_frame2.webp") as frame2:
|
||||||
frame1.save(
|
frame1.save(
|
||||||
temp_file,
|
temp_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[frame2, frame1, frame2, frame1],
|
append_images=(frame2, frame1, frame2, frame1),
|
||||||
duration=durations,
|
duration=durations,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ def test_seeking(tmp_path):
|
||||||
frame1.save(
|
frame1.save(
|
||||||
temp_file,
|
temp_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[frame2, frame1, frame2, frame1],
|
append_images=(frame2, frame1, frame2, frame1),
|
||||||
duration=dur,
|
duration=dur,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ def test_write_animated_metadata(tmp_path):
|
||||||
frame1.save(
|
frame1.save(
|
||||||
temp_file,
|
temp_file,
|
||||||
save_all=True,
|
save_all=True,
|
||||||
append_images=[frame2, frame1, frame2],
|
append_images=(frame2, frame1, frame2),
|
||||||
icc_profile=iccp_data,
|
icc_profile=iccp_data,
|
||||||
exif=exif_data,
|
exif=exif_data,
|
||||||
xmp=xmp_data,
|
xmp=xmp_data,
|
||||||
|
|
|
@ -54,10 +54,10 @@ def to_xxx_colorsys(im, func, mode):
|
||||||
|
|
||||||
conv_func = int_to_float
|
conv_func = int_to_float
|
||||||
|
|
||||||
converted = [
|
converted = (
|
||||||
tuple_to_ints(func(conv_func(_r), conv_func(_g), conv_func(_b)))
|
tuple_to_ints(func(conv_func(_r), conv_func(_g), conv_func(_b)))
|
||||||
for (_r, _g, _b) in itertools.zip_longest(r.tobytes(), g.tobytes(), b.tobytes())
|
for (_r, _g, _b) in itertools.zip_longest(r.tobytes(), g.tobytes(), b.tobytes())
|
||||||
]
|
)
|
||||||
|
|
||||||
new_bytes = b"".join(
|
new_bytes = b"".join(
|
||||||
bytes(chr(h) + chr(s) + chr(v), "latin-1") for (h, s, v) in converted
|
bytes(chr(h) + chr(s) + chr(v), "latin-1") for (h, s, v) in converted
|
||||||
|
|
|
@ -113,7 +113,7 @@ class TestImage:
|
||||||
with Image.open(PNGFILE, formats=123):
|
with Image.open(PNGFILE, formats=123):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for formats in [["JPEG"], ("JPEG",), ["jpeg"], ["Jpeg"], ["jPeG"], ["JpEg"]]:
|
for formats in (["JPEG"], ("JPEG",), ["jpeg"], ["Jpeg"], ["jPeG"], ["JpEg"]):
|
||||||
with pytest.raises(UnidentifiedImageError):
|
with pytest.raises(UnidentifiedImageError):
|
||||||
with Image.open(PNGFILE, formats=formats):
|
with Image.open(PNGFILE, formats=formats):
|
||||||
pass
|
pass
|
||||||
|
@ -122,7 +122,7 @@ class TestImage:
|
||||||
assert im.mode == "RGB"
|
assert im.mode == "RGB"
|
||||||
assert im.size == (128, 128)
|
assert im.size == (128, 128)
|
||||||
|
|
||||||
for file in [PNGFILE, JPGFILE]:
|
for file in (PNGFILE, JPGFILE):
|
||||||
with Image.open(file, formats=None) as im:
|
with Image.open(file, formats=None) as im:
|
||||||
assert im.mode == "RGB"
|
assert im.mode == "RGB"
|
||||||
assert im.size == (128, 128)
|
assert im.size == (128, 128)
|
||||||
|
@ -319,7 +319,7 @@ class TestImage:
|
||||||
# https://stackoverflow.com/questions/3374878
|
# https://stackoverflow.com/questions/3374878
|
||||||
# Arrange
|
# Arrange
|
||||||
expected_colors = sorted(
|
expected_colors = sorted(
|
||||||
[
|
(
|
||||||
(1122, (128, 127, 0, 255)),
|
(1122, (128, 127, 0, 255)),
|
||||||
(1089, (0, 255, 0, 255)),
|
(1089, (0, 255, 0, 255)),
|
||||||
(3300, (255, 0, 0, 255)),
|
(3300, (255, 0, 0, 255)),
|
||||||
|
@ -327,7 +327,7 @@ class TestImage:
|
||||||
(1122, (0, 255, 0, 128)),
|
(1122, (0, 255, 0, 128)),
|
||||||
(1122, (255, 0, 0, 128)),
|
(1122, (255, 0, 0, 128)),
|
||||||
(1089, (0, 255, 0, 0)),
|
(1089, (0, 255, 0, 0)),
|
||||||
]
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
dst = Image.new("RGBA", size=(100, 100), color=(0, 255, 0, 255))
|
dst = Image.new("RGBA", size=(100, 100), color=(0, 255, 0, 255))
|
||||||
|
@ -430,7 +430,7 @@ class TestImage:
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert extensions
|
assert extensions
|
||||||
for ext in [".cur", ".icns", ".tif", ".tiff"]:
|
for ext in (".cur", ".icns", ".tif", ".tiff"):
|
||||||
assert ext in extensions
|
assert ext in extensions
|
||||||
|
|
||||||
def test_effect_mandelbrot(self):
|
def test_effect_mandelbrot(self):
|
||||||
|
@ -474,7 +474,7 @@ class TestImage:
|
||||||
p2 = im.getpixel((0, 2))
|
p2 = im.getpixel((0, 2))
|
||||||
p3 = im.getpixel((0, 3))
|
p3 = im.getpixel((0, 3))
|
||||||
p4 = im.getpixel((0, 4))
|
p4 = im.getpixel((0, 4))
|
||||||
assert_not_all_same([p0, p1, p2, p3, p4])
|
assert_not_all_same((p0, p1, p2, p3, p4))
|
||||||
|
|
||||||
def test_effect_spread(self):
|
def test_effect_spread(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -520,7 +520,7 @@ class TestImage:
|
||||||
|
|
||||||
assert Image.new("RGB", (1, 1))
|
assert Image.new("RGB", (1, 1))
|
||||||
# Should pass lists too
|
# Should pass lists too
|
||||||
i = Image.new("RGB", [1, 1])
|
i = Image.new("RGB", (1, 1))
|
||||||
assert isinstance(i.size, tuple)
|
assert isinstance(i.size, tuple)
|
||||||
|
|
||||||
@pytest.mark.timeout(0.75)
|
@pytest.mark.timeout(0.75)
|
||||||
|
@ -598,7 +598,7 @@ class TestImage:
|
||||||
|
|
||||||
def test_register_extensions(self):
|
def test_register_extensions(self):
|
||||||
test_format = "a"
|
test_format = "a"
|
||||||
exts = ["b", "c"]
|
exts = ("b", "c")
|
||||||
for ext in exts:
|
for ext in exts:
|
||||||
Image.register_extension(test_format, ext)
|
Image.register_extension(test_format, ext)
|
||||||
ext_individual = Image.EXTENSION.copy()
|
ext_individual = Image.EXTENSION.copy()
|
||||||
|
@ -636,14 +636,14 @@ class TestImage:
|
||||||
im.putpixel((0, 1), 1)
|
im.putpixel((0, 1), 1)
|
||||||
im.info["transparency"] = 0
|
im.info["transparency"] = 0
|
||||||
|
|
||||||
im_remapped = im.remap_palette([1, 0])
|
im_remapped = im.remap_palette((1, 0))
|
||||||
assert im_remapped.info["transparency"] == 1
|
assert im_remapped.info["transparency"] == 1
|
||||||
assert len(im_remapped.getpalette()) == 6
|
assert len(im_remapped.getpalette()) == 6
|
||||||
|
|
||||||
# Test unused transparency
|
# Test unused transparency
|
||||||
im.info["transparency"] = 2
|
im.info["transparency"] = 2
|
||||||
|
|
||||||
im_remapped = im.remap_palette([1, 0])
|
im_remapped = im.remap_palette((1, 0))
|
||||||
assert "transparency" not in im_remapped.info
|
assert "transparency" not in im_remapped.info
|
||||||
|
|
||||||
def test__new(self):
|
def test__new(self):
|
||||||
|
@ -671,11 +671,11 @@ class TestImage:
|
||||||
_make_new(im, blank_pa, ImagePalette.ImagePalette())
|
_make_new(im, blank_pa, ImagePalette.ImagePalette())
|
||||||
|
|
||||||
def test_p_from_rgb_rgba(self):
|
def test_p_from_rgb_rgba(self):
|
||||||
for mode, color in [
|
for mode, color in (
|
||||||
("RGB", "#DDEEFF"),
|
("RGB", "#DDEEFF"),
|
||||||
("RGB", (221, 238, 255)),
|
("RGB", (221, 238, 255)),
|
||||||
("RGBA", (221, 238, 255, 255)),
|
("RGBA", (221, 238, 255, 255)),
|
||||||
]:
|
):
|
||||||
im = Image.new("P", (100, 100), color)
|
im = Image.new("P", (100, 100), color)
|
||||||
expected = Image.new(mode, (100, 100), color)
|
expected = Image.new(mode, (100, 100), color)
|
||||||
assert_image_equal(im.convert(mode), expected)
|
assert_image_equal(im.convert(mode), expected)
|
||||||
|
@ -943,7 +943,7 @@ class TestImage:
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"path",
|
"path",
|
||||||
[
|
(
|
||||||
"fli_overrun.bin",
|
"fli_overrun.bin",
|
||||||
"sgi_overrun.bin",
|
"sgi_overrun.bin",
|
||||||
"sgi_overrun_expandrow.bin",
|
"sgi_overrun_expandrow.bin",
|
||||||
|
@ -952,7 +952,7 @@ class TestImage:
|
||||||
"pcx_overrun2.bin",
|
"pcx_overrun2.bin",
|
||||||
"ossfuzz-4836216264589312.pcx",
|
"ossfuzz-4836216264589312.pcx",
|
||||||
"01r_00.pcx",
|
"01r_00.pcx",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_overrun(self, path):
|
def test_overrun(self, path):
|
||||||
"""For overrun completeness, test as:
|
"""For overrun completeness, test as:
|
||||||
|
|
|
@ -353,9 +353,9 @@ class TestCffi(AccessTest):
|
||||||
|
|
||||||
|
|
||||||
class TestImagePutPixelError(AccessTest):
|
class TestImagePutPixelError(AccessTest):
|
||||||
IMAGE_MODES1 = ["LA", "RGB", "RGBA", "BGR;15"]
|
IMAGE_MODES1 = ("LA", "RGB", "RGBA", "BGR;15")
|
||||||
IMAGE_MODES2 = ["L", "I", "I;16"]
|
IMAGE_MODES2 = ("L", "I", "I;16")
|
||||||
INVALID_TYPES = ["foo", 1.0, None]
|
INVALID_TYPES = ("foo", 1.0, None)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", IMAGE_MODES1)
|
@pytest.mark.parametrize("mode", IMAGE_MODES1)
|
||||||
def test_putpixel_type_error1(self, mode):
|
def test_putpixel_type_error1(self, mode):
|
||||||
|
|
|
@ -18,7 +18,7 @@ def draft_roundtrip(in_mode, in_size, req_mode, req_size):
|
||||||
|
|
||||||
|
|
||||||
def test_size():
|
def test_size():
|
||||||
for in_size, req_size, out_size in [
|
for in_size, req_size, out_size in (
|
||||||
((435, 361), (2048, 2048), (435, 361)), # bigger
|
((435, 361), (2048, 2048), (435, 361)), # bigger
|
||||||
((435, 361), (435, 361), (435, 361)), # same
|
((435, 361), (435, 361), (435, 361)), # same
|
||||||
((128, 128), (64, 64), (64, 64)),
|
((128, 128), (64, 64), (64, 64)),
|
||||||
|
@ -40,14 +40,14 @@ def test_size():
|
||||||
((435, 361), (32, 46), (109, 91)), # almost 8x
|
((435, 361), (32, 46), (109, 91)), # almost 8x
|
||||||
((435, 361), (32, 45), (55, 46)), # more than 8x
|
((435, 361), (32, 45), (55, 46)), # more than 8x
|
||||||
((435, 361), (16, 22), (55, 46)), # more than 16x
|
((435, 361), (16, 22), (55, 46)), # more than 16x
|
||||||
]:
|
):
|
||||||
im = draft_roundtrip("L", in_size, None, req_size)
|
im = draft_roundtrip("L", in_size, None, req_size)
|
||||||
im.load()
|
im.load()
|
||||||
assert im.size == out_size
|
assert im.size == out_size
|
||||||
|
|
||||||
|
|
||||||
def test_mode():
|
def test_mode():
|
||||||
for in_mode, req_mode, out_mode in [
|
for in_mode, req_mode, out_mode in (
|
||||||
("RGB", "1", "RGB"),
|
("RGB", "1", "RGB"),
|
||||||
("RGB", "L", "L"),
|
("RGB", "L", "L"),
|
||||||
("RGB", "RGB", "RGB"),
|
("RGB", "RGB", "RGB"),
|
||||||
|
@ -60,7 +60,7 @@ def test_mode():
|
||||||
("CMYK", "L", "CMYK"),
|
("CMYK", "L", "CMYK"),
|
||||||
("CMYK", "RGB", "CMYK"),
|
("CMYK", "RGB", "CMYK"),
|
||||||
("CMYK", "YCbCr", "CMYK"),
|
("CMYK", "YCbCr", "CMYK"),
|
||||||
]:
|
):
|
||||||
im = draft_roundtrip(in_mode, (64, 64), req_mode, None)
|
im = draft_roundtrip(in_mode, (64, 64), req_mode, None)
|
||||||
im.load()
|
im.load()
|
||||||
assert im.mode == out_mode
|
assert im.mode == out_mode
|
||||||
|
|
|
@ -70,7 +70,7 @@ def test_modefilter(mode, expected):
|
||||||
# 3 4 5
|
# 3 4 5
|
||||||
# 6 7 8
|
# 6 7 8
|
||||||
mod = im.filter(ImageFilter.ModeFilter).getpixel((1, 1))
|
mod = im.filter(ImageFilter.ModeFilter).getpixel((1, 1))
|
||||||
im.putdata([0, 0, 1, 2, 5, 1, 5, 2, 0]) # mode=0
|
im.putdata((0, 0, 1, 2, 5, 1, 5, 2, 0)) # mode=0
|
||||||
mod2 = im.filter(ImageFilter.ModeFilter).getpixel((1, 1))
|
mod2 = im.filter(ImageFilter.ModeFilter).getpixel((1, 1))
|
||||||
assert (mod, mod2) == expected
|
assert (mod, mod2) == expected
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,11 @@ pytestmark = pytest.mark.skipif(
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def test_images():
|
def test_images():
|
||||||
ims = [
|
ims = (
|
||||||
hopper(),
|
hopper(),
|
||||||
Image.open("Tests/images/transparent.png"),
|
Image.open("Tests/images/transparent.png"),
|
||||||
Image.open("Tests/images/7x13.png"),
|
Image.open("Tests/images/7x13.png"),
|
||||||
]
|
)
|
||||||
try:
|
try:
|
||||||
yield ims
|
yield ims
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -10,11 +10,11 @@ class TestImagingPaste:
|
||||||
size = 128
|
size = 128
|
||||||
|
|
||||||
def assert_9points_image(self, im, expected):
|
def assert_9points_image(self, im, expected):
|
||||||
expected = [
|
expected = tuple(
|
||||||
point[0] if im.mode == "L" else point[: len(im.mode)] for point in expected
|
point[0] if im.mode == "L" else point[: len(im.mode)] for point in expected
|
||||||
]
|
)
|
||||||
px = im.load()
|
px = im.load()
|
||||||
actual = [
|
actual = (
|
||||||
px[0, 0],
|
px[0, 0],
|
||||||
px[self.size // 2, 0],
|
px[self.size // 2, 0],
|
||||||
px[self.size - 1, 0],
|
px[self.size - 1, 0],
|
||||||
|
@ -24,7 +24,7 @@ class TestImagingPaste:
|
||||||
px[0, self.size - 1],
|
px[0, self.size - 1],
|
||||||
px[self.size // 2, self.size - 1],
|
px[self.size // 2, self.size - 1],
|
||||||
px[self.size - 1, self.size - 1],
|
px[self.size - 1, self.size - 1],
|
||||||
]
|
)
|
||||||
assert actual == expected
|
assert actual == expected
|
||||||
|
|
||||||
def assert_9points_paste(self, im, im2, mask, expected):
|
def assert_9points_paste(self, im, im2, mask, expected):
|
||||||
|
@ -62,48 +62,48 @@ class TestImagingPaste:
|
||||||
def gradient_RGB(self):
|
def gradient_RGB(self):
|
||||||
return Image.merge(
|
return Image.merge(
|
||||||
"RGB",
|
"RGB",
|
||||||
[
|
(
|
||||||
self.gradient_L,
|
self.gradient_L,
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_180),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_180),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@CachedProperty
|
@CachedProperty
|
||||||
def gradient_LA(self):
|
def gradient_LA(self):
|
||||||
return Image.merge(
|
return Image.merge(
|
||||||
"LA",
|
"LA",
|
||||||
[
|
(
|
||||||
self.gradient_L,
|
self.gradient_L,
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@CachedProperty
|
@CachedProperty
|
||||||
def gradient_RGBA(self):
|
def gradient_RGBA(self):
|
||||||
return Image.merge(
|
return Image.merge(
|
||||||
"RGBA",
|
"RGBA",
|
||||||
[
|
(
|
||||||
self.gradient_L,
|
self.gradient_L,
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_180),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_180),
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_270),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_270),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@CachedProperty
|
@CachedProperty
|
||||||
def gradient_RGBa(self):
|
def gradient_RGBa(self):
|
||||||
return Image.merge(
|
return Image.merge(
|
||||||
"RGBa",
|
"RGBa",
|
||||||
[
|
(
|
||||||
self.gradient_L,
|
self.gradient_L,
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_90),
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_180),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_180),
|
||||||
self.gradient_L.transpose(Image.Transpose.ROTATE_270),
|
self.gradient_L.transpose(Image.Transpose.ROTATE_270),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_image_solid(self, mode):
|
def test_image_solid(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "red")
|
im = Image.new(mode, (200, 200), "red")
|
||||||
im2 = getattr(self, "gradient_" + mode)
|
im2 = getattr(self, "gradient_" + mode)
|
||||||
|
@ -113,7 +113,7 @@ class TestImagingPaste:
|
||||||
im = im.crop((12, 23, im2.width + 12, im2.height + 23))
|
im = im.crop((12, 23, im2.width + 12, im2.height + 23))
|
||||||
assert_image_equal(im, im2)
|
assert_image_equal(im, im2)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_image_mask_1(self, mode):
|
def test_image_mask_1(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "white")
|
im = Image.new(mode, (200, 200), "white")
|
||||||
im2 = getattr(self, "gradient_" + mode)
|
im2 = getattr(self, "gradient_" + mode)
|
||||||
|
@ -122,7 +122,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
im2,
|
im2,
|
||||||
self.mask_1,
|
self.mask_1,
|
||||||
[
|
(
|
||||||
(255, 255, 255, 255),
|
(255, 255, 255, 255),
|
||||||
(255, 255, 255, 255),
|
(255, 255, 255, 255),
|
||||||
(127, 254, 127, 0),
|
(127, 254, 127, 0),
|
||||||
|
@ -132,10 +132,10 @@ class TestImagingPaste:
|
||||||
(127, 0, 127, 254),
|
(127, 0, 127, 254),
|
||||||
(191, 64, 63, 190),
|
(191, 64, 63, 190),
|
||||||
(255, 255, 255, 255),
|
(255, 255, 255, 255),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_image_mask_L(self, mode):
|
def test_image_mask_L(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "white")
|
im = Image.new(mode, (200, 200), "white")
|
||||||
im2 = getattr(self, "gradient_" + mode)
|
im2 = getattr(self, "gradient_" + mode)
|
||||||
|
@ -144,7 +144,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
im2,
|
im2,
|
||||||
self.mask_L,
|
self.mask_L,
|
||||||
[
|
(
|
||||||
(128, 191, 255, 191),
|
(128, 191, 255, 191),
|
||||||
(208, 239, 239, 208),
|
(208, 239, 239, 208),
|
||||||
(255, 255, 255, 255),
|
(255, 255, 255, 255),
|
||||||
|
@ -154,10 +154,10 @@ class TestImagingPaste:
|
||||||
(128, 1, 128, 254),
|
(128, 1, 128, 254),
|
||||||
(207, 113, 112, 207),
|
(207, 113, 112, 207),
|
||||||
(255, 191, 128, 191),
|
(255, 191, 128, 191),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_image_mask_LA(self, mode):
|
def test_image_mask_LA(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "white")
|
im = Image.new(mode, (200, 200), "white")
|
||||||
im2 = getattr(self, "gradient_" + mode)
|
im2 = getattr(self, "gradient_" + mode)
|
||||||
|
@ -166,7 +166,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
im2,
|
im2,
|
||||||
self.gradient_LA,
|
self.gradient_LA,
|
||||||
[
|
(
|
||||||
(128, 191, 255, 191),
|
(128, 191, 255, 191),
|
||||||
(112, 207, 206, 111),
|
(112, 207, 206, 111),
|
||||||
(128, 254, 128, 1),
|
(128, 254, 128, 1),
|
||||||
|
@ -176,10 +176,10 @@ class TestImagingPaste:
|
||||||
(255, 255, 255, 255),
|
(255, 255, 255, 255),
|
||||||
(239, 207, 207, 239),
|
(239, 207, 207, 239),
|
||||||
(255, 191, 128, 191),
|
(255, 191, 128, 191),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_image_mask_RGBA(self, mode):
|
def test_image_mask_RGBA(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "white")
|
im = Image.new(mode, (200, 200), "white")
|
||||||
im2 = getattr(self, "gradient_" + mode)
|
im2 = getattr(self, "gradient_" + mode)
|
||||||
|
@ -188,7 +188,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
im2,
|
im2,
|
||||||
self.gradient_RGBA,
|
self.gradient_RGBA,
|
||||||
[
|
(
|
||||||
(128, 191, 255, 191),
|
(128, 191, 255, 191),
|
||||||
(208, 239, 239, 208),
|
(208, 239, 239, 208),
|
||||||
(255, 255, 255, 255),
|
(255, 255, 255, 255),
|
||||||
|
@ -198,10 +198,10 @@ class TestImagingPaste:
|
||||||
(128, 1, 128, 254),
|
(128, 1, 128, 254),
|
||||||
(207, 113, 112, 207),
|
(207, 113, 112, 207),
|
||||||
(255, 191, 128, 191),
|
(255, 191, 128, 191),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_image_mask_RGBa(self, mode):
|
def test_image_mask_RGBa(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "white")
|
im = Image.new(mode, (200, 200), "white")
|
||||||
im2 = getattr(self, "gradient_" + mode)
|
im2 = getattr(self, "gradient_" + mode)
|
||||||
|
@ -210,7 +210,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
im2,
|
im2,
|
||||||
self.gradient_RGBa,
|
self.gradient_RGBa,
|
||||||
[
|
(
|
||||||
(128, 255, 126, 255),
|
(128, 255, 126, 255),
|
||||||
(0, 127, 126, 255),
|
(0, 127, 126, 255),
|
||||||
(126, 253, 126, 255),
|
(126, 253, 126, 255),
|
||||||
|
@ -220,10 +220,10 @@ class TestImagingPaste:
|
||||||
(128, 1, 128, 255),
|
(128, 1, 128, 255),
|
||||||
(0, 129, 128, 255),
|
(0, 129, 128, 255),
|
||||||
(126, 255, 128, 255),
|
(126, 255, 128, 255),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_color_solid(self, mode):
|
def test_color_solid(self, mode):
|
||||||
im = Image.new(mode, (200, 200), "black")
|
im = Image.new(mode, (200, 200), "black")
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ class TestImagingPaste:
|
||||||
assert head[255] == 128 * 128
|
assert head[255] == 128 * 128
|
||||||
assert sum(head[:255]) == 0
|
assert sum(head[:255]) == 0
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_color_mask_1(self, mode):
|
def test_color_mask_1(self, mode):
|
||||||
im = Image.new(mode, (200, 200), (50, 60, 70, 80)[: len(mode)])
|
im = Image.new(mode, (200, 200), (50, 60, 70, 80)[: len(mode)])
|
||||||
color = (10, 20, 30, 40)[: len(mode)]
|
color = (10, 20, 30, 40)[: len(mode)]
|
||||||
|
@ -245,7 +245,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
color,
|
color,
|
||||||
self.mask_1,
|
self.mask_1,
|
||||||
[
|
(
|
||||||
(50, 60, 70, 80),
|
(50, 60, 70, 80),
|
||||||
(50, 60, 70, 80),
|
(50, 60, 70, 80),
|
||||||
(10, 20, 30, 40),
|
(10, 20, 30, 40),
|
||||||
|
@ -255,10 +255,10 @@ class TestImagingPaste:
|
||||||
(10, 20, 30, 40),
|
(10, 20, 30, 40),
|
||||||
(10, 20, 30, 40),
|
(10, 20, 30, 40),
|
||||||
(50, 60, 70, 80),
|
(50, 60, 70, 80),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_color_mask_L(self, mode):
|
def test_color_mask_L(self, mode):
|
||||||
im = getattr(self, "gradient_" + mode).copy()
|
im = getattr(self, "gradient_" + mode).copy()
|
||||||
color = "white"
|
color = "white"
|
||||||
|
@ -267,7 +267,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
color,
|
color,
|
||||||
self.mask_L,
|
self.mask_L,
|
||||||
[
|
(
|
||||||
(127, 191, 254, 191),
|
(127, 191, 254, 191),
|
||||||
(111, 207, 206, 110),
|
(111, 207, 206, 110),
|
||||||
(127, 254, 127, 0),
|
(127, 254, 127, 0),
|
||||||
|
@ -277,10 +277,10 @@ class TestImagingPaste:
|
||||||
(254, 254, 254, 255),
|
(254, 254, 254, 255),
|
||||||
(239, 206, 206, 238),
|
(239, 206, 206, 238),
|
||||||
(254, 191, 127, 191),
|
(254, 191, 127, 191),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_color_mask_RGBA(self, mode):
|
def test_color_mask_RGBA(self, mode):
|
||||||
im = getattr(self, "gradient_" + mode).copy()
|
im = getattr(self, "gradient_" + mode).copy()
|
||||||
color = "white"
|
color = "white"
|
||||||
|
@ -289,7 +289,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
color,
|
color,
|
||||||
self.gradient_RGBA,
|
self.gradient_RGBA,
|
||||||
[
|
(
|
||||||
(127, 191, 254, 191),
|
(127, 191, 254, 191),
|
||||||
(111, 207, 206, 110),
|
(111, 207, 206, 110),
|
||||||
(127, 254, 127, 0),
|
(127, 254, 127, 0),
|
||||||
|
@ -299,10 +299,10 @@ class TestImagingPaste:
|
||||||
(254, 254, 254, 255),
|
(254, 254, 254, 255),
|
||||||
(239, 206, 206, 238),
|
(239, 206, 206, 238),
|
||||||
(254, 191, 127, 191),
|
(254, 191, 127, 191),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
|
@pytest.mark.parametrize("mode", ("RGBA", "RGB", "L"))
|
||||||
def test_color_mask_RGBa(self, mode):
|
def test_color_mask_RGBa(self, mode):
|
||||||
im = getattr(self, "gradient_" + mode).copy()
|
im = getattr(self, "gradient_" + mode).copy()
|
||||||
color = "white"
|
color = "white"
|
||||||
|
@ -311,7 +311,7 @@ class TestImagingPaste:
|
||||||
im,
|
im,
|
||||||
color,
|
color,
|
||||||
self.gradient_RGBa,
|
self.gradient_RGBa,
|
||||||
[
|
(
|
||||||
(255, 63, 126, 63),
|
(255, 63, 126, 63),
|
||||||
(47, 143, 142, 46),
|
(47, 143, 142, 46),
|
||||||
(126, 253, 126, 255),
|
(126, 253, 126, 255),
|
||||||
|
@ -321,7 +321,7 @@ class TestImagingPaste:
|
||||||
(255, 255, 255, 0),
|
(255, 255, 255, 0),
|
||||||
(48, 15, 15, 47),
|
(48, 15, 15, 47),
|
||||||
(126, 63, 255, 63),
|
(126, 63, 255, 63),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_different_sizes(self):
|
def test_different_sizes(self):
|
||||||
|
|
|
@ -16,7 +16,7 @@ def test_putpalette():
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
palette("1")
|
palette("1")
|
||||||
for mode in ["L", "LA", "P", "PA"]:
|
for mode in ("L", "LA", "P", "PA"):
|
||||||
assert palette(mode) == (
|
assert palette(mode) == (
|
||||||
"PA" if "A" in mode else "P",
|
"PA" if "A" in mode else "P",
|
||||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||||
|
|
|
@ -8,7 +8,7 @@ codecs = dir(Image.core)
|
||||||
|
|
||||||
|
|
||||||
# There are several internal implementations
|
# There are several internal implementations
|
||||||
remarkable_factors = [
|
remarkable_factors = (
|
||||||
# special implementations
|
# special implementations
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
|
@ -32,7 +32,7 @@ remarkable_factors = [
|
||||||
(4, 7),
|
(4, 7),
|
||||||
(5, 7),
|
(5, 7),
|
||||||
(19, 17),
|
(19, 17),
|
||||||
]
|
)
|
||||||
|
|
||||||
gradients_image = Image.open("Tests/images/radial_gradients.png")
|
gradients_image = Image.open("Tests/images/radial_gradients.png")
|
||||||
gradients_image.load()
|
gradients_image.load()
|
||||||
|
|
|
@ -482,7 +482,7 @@ class TestCoreResampleBox:
|
||||||
dst_size = (251, 188)
|
dst_size = (251, 188)
|
||||||
reference = im.resize(dst_size, Image.Resampling.BICUBIC)
|
reference = im.resize(dst_size, Image.Resampling.BICUBIC)
|
||||||
|
|
||||||
for tiles in [(1, 1), (3, 3), (9, 7), (100, 100)]:
|
for tiles in ((1, 1), (3, 3), (9, 7), (100, 100)):
|
||||||
tiled = self.resize_tiled(im, dst_size, *tiles)
|
tiled = self.resize_tiled(im, dst_size, *tiles)
|
||||||
assert_image_similar(reference, tiled, 0.01)
|
assert_image_similar(reference, tiled, 0.01)
|
||||||
|
|
||||||
|
@ -527,12 +527,12 @@ class TestCoreResampleBox:
|
||||||
# When no resize is required
|
# When no resize is required
|
||||||
im = hopper()
|
im = hopper()
|
||||||
|
|
||||||
for size, box in [
|
for size, box in (
|
||||||
((40, 50), (0, 0, 40, 50)),
|
((40, 50), (0, 0, 40, 50)),
|
||||||
((40, 50), (0, 10, 40, 60)),
|
((40, 50), (0, 10, 40, 60)),
|
||||||
((40, 50), (10, 0, 50, 50)),
|
((40, 50), (10, 0, 50, 50)),
|
||||||
((40, 50), (10, 20, 50, 70)),
|
((40, 50), (10, 20, 50, 70)),
|
||||||
]:
|
):
|
||||||
res = im.resize(size, Image.Resampling.LANCZOS, box)
|
res = im.resize(size, Image.Resampling.LANCZOS, box)
|
||||||
assert res.size == size
|
assert res.size == size
|
||||||
assert_image_equal(res, im.crop(box), f">>> {size} {box}")
|
assert_image_equal(res, im.crop(box), f">>> {size} {box}")
|
||||||
|
@ -541,12 +541,12 @@ class TestCoreResampleBox:
|
||||||
# When resize is required
|
# When resize is required
|
||||||
im = hopper()
|
im = hopper()
|
||||||
|
|
||||||
for size, box in [
|
for size, box in (
|
||||||
((40, 50), (0.4, 0.4, 40.4, 50.4)),
|
((40, 50), (0.4, 0.4, 40.4, 50.4)),
|
||||||
((40, 50), (0.4, 10.4, 40.4, 60.4)),
|
((40, 50), (0.4, 10.4, 40.4, 60.4)),
|
||||||
((40, 50), (10.4, 0.4, 50.4, 50.4)),
|
((40, 50), (10.4, 0.4, 50.4, 50.4)),
|
||||||
((40, 50), (10.4, 20.4, 50.4, 70.4)),
|
((40, 50), (10.4, 20.4, 50.4, 70.4)),
|
||||||
]:
|
):
|
||||||
res = im.resize(size, Image.Resampling.LANCZOS, box)
|
res = im.resize(size, Image.Resampling.LANCZOS, box)
|
||||||
assert res.size == size
|
assert res.size == size
|
||||||
with pytest.raises(AssertionError, match=r"difference \d"):
|
with pytest.raises(AssertionError, match=r"difference \d"):
|
||||||
|
@ -560,12 +560,12 @@ class TestCoreResampleBox:
|
||||||
# Can skip resize for one dimension
|
# Can skip resize for one dimension
|
||||||
im = hopper()
|
im = hopper()
|
||||||
|
|
||||||
for size, box in [
|
for size, box in (
|
||||||
((40, 50), (0, 0, 40, 90)),
|
((40, 50), (0, 0, 40, 90)),
|
||||||
((40, 50), (0, 20, 40, 90)),
|
((40, 50), (0, 20, 40, 90)),
|
||||||
((40, 50), (10, 0, 50, 90)),
|
((40, 50), (10, 0, 50, 90)),
|
||||||
((40, 50), (10, 20, 50, 90)),
|
((40, 50), (10, 20, 50, 90)),
|
||||||
]:
|
):
|
||||||
res = im.resize(size, flt, box)
|
res = im.resize(size, flt, box)
|
||||||
assert res.size == size
|
assert res.size == size
|
||||||
# Borders should be slightly different
|
# Borders should be slightly different
|
||||||
|
@ -583,12 +583,12 @@ class TestCoreResampleBox:
|
||||||
# Can skip resize for one dimension
|
# Can skip resize for one dimension
|
||||||
im = hopper()
|
im = hopper()
|
||||||
|
|
||||||
for size, box in [
|
for size, box in (
|
||||||
((40, 50), (0, 0, 90, 50)),
|
((40, 50), (0, 0, 90, 50)),
|
||||||
((40, 50), (20, 0, 90, 50)),
|
((40, 50), (20, 0, 90, 50)),
|
||||||
((40, 50), (0, 10, 90, 60)),
|
((40, 50), (0, 10, 90, 60)),
|
||||||
((40, 50), (20, 10, 90, 60)),
|
((40, 50), (20, 10, 90, 60)),
|
||||||
]:
|
):
|
||||||
res = im.resize(size, flt, box)
|
res = im.resize(size, flt, box)
|
||||||
assert res.size == size
|
assert res.size == size
|
||||||
# Borders should be slightly different
|
# Borders should be slightly different
|
||||||
|
|
|
@ -39,7 +39,7 @@ class TestImagingCoreResize:
|
||||||
self.resize(hopper("P"), (15, 12), Image.Resampling.BILINEAR)
|
self.resize(hopper("P"), (15, 12), Image.Resampling.BILINEAR)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.resize(hopper("I;16"), (15, 12), Image.Resampling.BILINEAR)
|
self.resize(hopper("I;16"), (15, 12), Image.Resampling.BILINEAR)
|
||||||
for mode in ["L", "I", "F", "RGB", "RGBA", "CMYK", "YCbCr"]:
|
for mode in ("L", "I", "F", "RGB", "RGBA", "CMYK", "YCbCr"):
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
r = self.resize(im, (15, 12), Image.Resampling.BILINEAR)
|
r = self.resize(im, (15, 12), Image.Resampling.BILINEAR)
|
||||||
assert r.mode == mode
|
assert r.mode == mode
|
||||||
|
|
|
@ -35,7 +35,7 @@ class TestImageTransform:
|
||||||
def test_palette(self):
|
def test_palette(self):
|
||||||
with Image.open("Tests/images/hopper.gif") as im:
|
with Image.open("Tests/images/hopper.gif") as im:
|
||||||
transformed = im.transform(
|
transformed = im.transform(
|
||||||
im.size, Image.Transform.AFFINE, [1, 0, 0, 0, 1, 0]
|
im.size, Image.Transform.AFFINE, (1, 0, 0, 0, 1, 0)
|
||||||
)
|
)
|
||||||
assert im.palette.palette == transformed.palette.palette
|
assert im.palette.palette == transformed.palette.palette
|
||||||
|
|
||||||
|
@ -276,11 +276,11 @@ class TestImageTransformAffine:
|
||||||
else:
|
else:
|
||||||
transposed = im
|
transposed = im
|
||||||
|
|
||||||
for resample in [
|
for resample in (
|
||||||
Image.Resampling.NEAREST,
|
Image.Resampling.NEAREST,
|
||||||
Image.Resampling.BILINEAR,
|
Image.Resampling.BILINEAR,
|
||||||
Image.Resampling.BICUBIC,
|
Image.Resampling.BICUBIC,
|
||||||
]:
|
):
|
||||||
transformed = im.transform(
|
transformed = im.transform(
|
||||||
transposed.size, self.transform, matrix, resample
|
transposed.size, self.transform, matrix, resample
|
||||||
)
|
)
|
||||||
|
@ -308,8 +308,8 @@ class TestImageTransformAffine:
|
||||||
im = self._test_image()
|
im = self._test_image()
|
||||||
|
|
||||||
size_up = int(round(im.width * scale)), int(round(im.height * scale))
|
size_up = int(round(im.width * scale)), int(round(im.height * scale))
|
||||||
matrix_up = [1 / scale, 0, 0, 0, 1 / scale, 0, 0, 0]
|
matrix_up = (1 / scale, 0, 0, 0, 1 / scale, 0, 0, 0)
|
||||||
matrix_down = [scale, 0, 0, 0, scale, 0, 0, 0]
|
matrix_down = (scale, 0, 0, 0, scale, 0, 0, 0)
|
||||||
|
|
||||||
transformed = im.transform(size_up, self.transform, matrix_up, resample)
|
transformed = im.transform(size_up, self.transform, matrix_up, resample)
|
||||||
transformed = transformed.transform(
|
transformed = transformed.transform(
|
||||||
|
@ -337,8 +337,8 @@ class TestImageTransformAffine:
|
||||||
im = self._test_image()
|
im = self._test_image()
|
||||||
|
|
||||||
size_up = int(round(im.width + x)), int(round(im.height + y))
|
size_up = int(round(im.width + x)), int(round(im.height + y))
|
||||||
matrix_up = [1, 0, -x, 0, 1, -y, 0, 0]
|
matrix_up = (1, 0, -x, 0, 1, -y, 0, 0)
|
||||||
matrix_down = [1, 0, x, 0, 1, y, 0, 0]
|
matrix_down = (1, 0, x, 0, 1, y, 0, 0)
|
||||||
|
|
||||||
transformed = im.transform(size_up, self.transform, matrix_up, resample)
|
transformed = im.transform(size_up, self.transform, matrix_up, resample)
|
||||||
transformed = transformed.transform(
|
transformed = transformed.transform(
|
||||||
|
|
|
@ -7,7 +7,7 @@ from .helper import assert_image_equal
|
||||||
|
|
||||||
HOPPER = {
|
HOPPER = {
|
||||||
mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy()
|
mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy()
|
||||||
for mode in ["L", "RGB", "I;16", "I;16L", "I;16B"]
|
for mode in ("L", "RGB", "I;16", "I;16L", "I;16B")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ def test_sanity():
|
||||||
|
|
||||||
v = ImageCms.versions() # should return four strings
|
v = ImageCms.versions() # should return four strings
|
||||||
assert v[0] == "1.0.0 pil"
|
assert v[0] == "1.0.0 pil"
|
||||||
assert list(map(type, v)) == [str, str, str, str]
|
assert tuple(map(type, v)) == (str, str, str, str)
|
||||||
|
|
||||||
# internal version number
|
# internal version number
|
||||||
assert re.search(r"\d+\.\d+(\.\d+)?$", features.version_module("littlecms2"))
|
assert re.search(r"\d+\.\d+(\.\d+)?$", features.version_module("littlecms2"))
|
||||||
|
@ -493,11 +493,11 @@ def assert_aux_channel_preserved(mode, transform_in_place, preserved_channel):
|
||||||
def create_test_image():
|
def create_test_image():
|
||||||
# set up test image with something interesting in the tested aux channel.
|
# set up test image with something interesting in the tested aux channel.
|
||||||
# fmt: off
|
# fmt: off
|
||||||
nine_grid_deltas = [
|
nine_grid_deltas = (
|
||||||
(-1, -1), (-1, 0), (-1, 1),
|
(-1, -1), (-1, 0), (-1, 1),
|
||||||
(0, -1), (0, 0), (0, 1),
|
(0, -1), (0, 0), (0, 1),
|
||||||
(1, -1), (1, 0), (1, 1),
|
(1, -1), (1, 0), (1, 1),
|
||||||
]
|
)
|
||||||
# fmt: on
|
# fmt: on
|
||||||
chans = []
|
chans = []
|
||||||
bands = ImageMode.getmode(mode).bands
|
bands = ImageMode.getmode(mode).bands
|
||||||
|
@ -570,15 +570,15 @@ def test_preserve_auxiliary_channels_rgbx_in_place():
|
||||||
|
|
||||||
def test_auxiliary_channels_isolated():
|
def test_auxiliary_channels_isolated():
|
||||||
# test data in aux channels does not affect non-aux channels
|
# test data in aux channels does not affect non-aux channels
|
||||||
aux_channel_formats = [
|
aux_channel_formats = (
|
||||||
# format, profile, color-only format, source test image
|
# format, profile, color-only format, source test image
|
||||||
("RGBA", "sRGB", "RGB", hopper("RGBA")),
|
("RGBA", "sRGB", "RGB", hopper("RGBA")),
|
||||||
("RGBX", "sRGB", "RGB", hopper("RGBX")),
|
("RGBX", "sRGB", "RGB", hopper("RGBX")),
|
||||||
("LAB", "LAB", "LAB", Image.open("Tests/images/hopper.Lab.tif")),
|
("LAB", "LAB", "LAB", Image.open("Tests/images/hopper.Lab.tif")),
|
||||||
]
|
)
|
||||||
for src_format in aux_channel_formats:
|
for src_format in aux_channel_formats:
|
||||||
for dst_format in aux_channel_formats:
|
for dst_format in aux_channel_formats:
|
||||||
for transform_in_place in [True, False]:
|
for transform_in_place in (True, False):
|
||||||
# inplace only if format doesn't change
|
# inplace only if format doesn't change
|
||||||
if transform_in_place and src_format[0] != dst_format[0]:
|
if transform_in_place and src_format[0] != dst_format[0]:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -174,8 +174,8 @@ def test_arc_high():
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.arc([10, 10, 89, 189], 20, 330, width=20, fill="white")
|
draw.arc((10, 10, 89, 189), 20, 330, width=20, fill="white")
|
||||||
draw.arc([110, 10, 189, 189], 20, 150, width=20, fill="white")
|
draw.arc((110, 10, 189, 189), 20, 150, width=20, fill="white")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_equal_tofile(im, "Tests/images/imagedraw_arc_high.png")
|
assert_image_equal_tofile(im, "Tests/images/imagedraw_arc_high.png")
|
||||||
|
@ -255,7 +255,7 @@ def test_chord_too_fat():
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.chord([-150, -150, 99, 99], 15, 60, width=10, fill="white", outline="red")
|
draw.chord((-150, -150, 99, 99), 15, 60, width=10, fill="white", outline="red")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_equal_tofile(im, "Tests/images/imagedraw_chord_too_fat.png")
|
assert_image_equal_tofile(im, "Tests/images/imagedraw_chord_too_fat.png")
|
||||||
|
@ -537,7 +537,7 @@ def test_pieslice_wide():
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.pieslice([0, 0, 199, 99], 190, 170, width=10, fill="white", outline="red")
|
draw.pieslice((0, 0, 199, 99), 190, 170, width=10, fill="white", outline="red")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_equal_tofile(im, "Tests/images/imagedraw_pieslice_wide.png")
|
assert_image_equal_tofile(im, "Tests/images/imagedraw_pieslice_wide.png")
|
||||||
|
@ -563,12 +563,12 @@ def test_pieslice_no_spikes():
|
||||||
|
|
||||||
for cx, cy, angle in zip(cxs, cys, range(0, 360, 15)):
|
for cx, cy, angle in zip(cxs, cys, range(0, 360, 15)):
|
||||||
draw.pieslice(
|
draw.pieslice(
|
||||||
[cx - 100, cy - 100, cx + 100, cy + 100], angle, angle + 1, fill="black"
|
(cx - 100, cy - 100, cx + 100, cy + 100), angle, angle + 1, fill="black"
|
||||||
)
|
)
|
||||||
draw.point([cx, cy], fill="red")
|
draw.point((cx, cy), fill="red")
|
||||||
|
|
||||||
im_pre_erase = im.copy()
|
im_pre_erase = im.copy()
|
||||||
draw.rectangle([21, 21, 139, 139], fill="white")
|
draw.rectangle((21, 21, 139, 139), fill="white")
|
||||||
|
|
||||||
assert_image_equal(im, im_pre_erase)
|
assert_image_equal(im, im_pre_erase)
|
||||||
|
|
||||||
|
@ -624,7 +624,7 @@ def test_polygon_1px_high():
|
||||||
expected = "Tests/images/imagedraw_polygon_1px_high.png"
|
expected = "Tests/images/imagedraw_polygon_1px_high.png"
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.polygon([(0, 1), (0, 1), (2, 1), (2, 1)], "#f00")
|
draw.polygon(((0, 1), (0, 1), (2, 1), (2, 1)), "#f00")
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_equal_tofile(im, expected)
|
assert_image_equal_tofile(im, expected)
|
||||||
|
@ -638,7 +638,7 @@ def test_polygon_1px_high_translucent():
|
||||||
expected = "Tests/images/imagedraw_polygon_1px_high_translucent.png"
|
expected = "Tests/images/imagedraw_polygon_1px_high_translucent.png"
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.polygon([(1, 1), (1, 1), (3, 1), (3, 1)], (255, 0, 0, 127))
|
draw.polygon(((1, 1), (1, 1), (3, 1), (3, 1)), (255, 0, 0, 127))
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_equal_tofile(im, expected)
|
assert_image_equal_tofile(im, expected)
|
||||||
|
@ -650,7 +650,7 @@ def test_polygon_translucent():
|
||||||
draw = ImageDraw.Draw(im, "RGBA")
|
draw = ImageDraw.Draw(im, "RGBA")
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.polygon([(20, 80), (80, 80), (80, 20)], fill=(0, 255, 0, 127))
|
draw.polygon(((20, 80), (80, 80), (80, 20)), fill=(0, 255, 0, 127))
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
expected = "Tests/images/imagedraw_polygon_translucent.png"
|
expected = "Tests/images/imagedraw_polygon_translucent.png"
|
||||||
|
@ -674,7 +674,7 @@ def test_big_rectangle():
|
||||||
# Test drawing a rectangle bigger than the image
|
# Test drawing a rectangle bigger than the image
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
bbox = [(-1, -1), (W + 1, H + 1)]
|
bbox = ((-1, -1), (W + 1, H + 1))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
|
@ -755,7 +755,7 @@ def test_rectangle_translucent_outline(bbox):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"xy",
|
"xy",
|
||||||
[(10, 20, 190, 180), ([10, 20], [190, 180]), ((10, 20), (190, 180))],
|
((10, 20, 190, 180), ([10, 20], [190, 180]), ((10, 20), (190, 180))),
|
||||||
)
|
)
|
||||||
def test_rounded_rectangle(xy):
|
def test_rounded_rectangle(xy):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -801,11 +801,11 @@ def test_rounded_rectangle_corners(top_left, top_right, bottom_right, bottom_lef
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"xy, radius, type",
|
"xy, radius, type",
|
||||||
[
|
(
|
||||||
((10, 20, 190, 180), 30.5, "given"),
|
((10, 20, 190, 180), 30.5, "given"),
|
||||||
((10, 10, 181, 190), 90, "width"),
|
((10, 10, 181, 190), 90, "width"),
|
||||||
((10, 20, 190, 181), 85, "height"),
|
((10, 20, 190, 181), 85, "height"),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_rounded_rectangle_non_integer_radius(xy, radius, type):
|
def test_rounded_rectangle_non_integer_radius(xy, radius, type):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -837,11 +837,11 @@ def test_rounded_rectangle_zero_radius(bbox):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"xy, suffix",
|
"xy, suffix",
|
||||||
[
|
(
|
||||||
((20, 10, 80, 90), "x"),
|
((20, 10, 80, 90), "x"),
|
||||||
((10, 20, 90, 80), "y"),
|
((10, 20, 90, 80), "y"),
|
||||||
((20, 20, 80, 80), "both"),
|
((20, 20, 80, 80), "both"),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_rounded_rectangle_translucent(xy, suffix):
|
def test_rounded_rectangle_translucent(xy, suffix):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -863,7 +863,7 @@ def test_rounded_rectangle_translucent(xy, suffix):
|
||||||
def test_floodfill(bbox):
|
def test_floodfill(bbox):
|
||||||
red = ImageColor.getrgb("red")
|
red = ImageColor.getrgb("red")
|
||||||
|
|
||||||
for mode, value in [("L", 1), ("RGBA", (255, 0, 0, 0)), ("RGB", red)]:
|
for mode, value in (("L", 1), ("RGBA", (255, 0, 0, 0)), ("RGB", red)):
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new(mode, (W, H))
|
im = Image.new(mode, (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
@ -962,10 +962,10 @@ def create_base_image_draw(
|
||||||
def test_square():
|
def test_square():
|
||||||
expected = os.path.join(IMAGES_PATH, "square.png")
|
expected = os.path.join(IMAGES_PATH, "square.png")
|
||||||
img, draw = create_base_image_draw((10, 10))
|
img, draw = create_base_image_draw((10, 10))
|
||||||
draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK)
|
draw.polygon(((2, 2), (2, 7), (7, 7), (7, 2)), BLACK)
|
||||||
assert_image_equal_tofile(img, expected, "square as normal polygon failed")
|
assert_image_equal_tofile(img, expected, "square as normal polygon failed")
|
||||||
img, draw = create_base_image_draw((10, 10))
|
img, draw = create_base_image_draw((10, 10))
|
||||||
draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK)
|
draw.polygon(((7, 7), (7, 2), (2, 2), (2, 7)), BLACK)
|
||||||
assert_image_equal_tofile(img, expected, "square as inverted polygon failed")
|
assert_image_equal_tofile(img, expected, "square as inverted polygon failed")
|
||||||
img, draw = create_base_image_draw((10, 10))
|
img, draw = create_base_image_draw((10, 10))
|
||||||
draw.rectangle((2, 2, 7, 7), BLACK)
|
draw.rectangle((2, 2, 7, 7), BLACK)
|
||||||
|
@ -974,7 +974,7 @@ def test_square():
|
||||||
|
|
||||||
def test_triangle_right():
|
def test_triangle_right():
|
||||||
img, draw = create_base_image_draw((20, 20))
|
img, draw = create_base_image_draw((20, 20))
|
||||||
draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK)
|
draw.polygon(((3, 5), (17, 5), (10, 12)), BLACK)
|
||||||
assert_image_equal_tofile(
|
assert_image_equal_tofile(
|
||||||
img, os.path.join(IMAGES_PATH, "triangle_right.png"), "triangle right failed"
|
img, os.path.join(IMAGES_PATH, "triangle_right.png"), "triangle right failed"
|
||||||
)
|
)
|
||||||
|
@ -986,7 +986,7 @@ def test_triangle_right():
|
||||||
)
|
)
|
||||||
def test_triangle_right_width(fill, suffix):
|
def test_triangle_right_width(fill, suffix):
|
||||||
img, draw = create_base_image_draw((100, 100))
|
img, draw = create_base_image_draw((100, 100))
|
||||||
draw.polygon([(15, 25), (85, 25), (50, 60)], fill, WHITE, width=5)
|
draw.polygon(((15, 25), (85, 25), (50, 60)), fill, WHITE, width=5)
|
||||||
assert_image_equal_tofile(
|
assert_image_equal_tofile(
|
||||||
img, os.path.join(IMAGES_PATH, "triangle_right_" + suffix + ".png")
|
img, os.path.join(IMAGES_PATH, "triangle_right_" + suffix + ".png")
|
||||||
)
|
)
|
||||||
|
@ -1116,7 +1116,7 @@ def test_wide_line_dot():
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.line([(50, 50), (50, 50)], width=3)
|
draw.line(((50, 50), (50, 50)), width=3)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar_tofile(im, "Tests/images/imagedraw_wide_line_dot.png", 1)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_wide_line_dot.png", 1)
|
||||||
|
@ -1129,7 +1129,7 @@ def test_wide_line_larger_than_int():
|
||||||
expected = "Tests/images/imagedraw_wide_line_larger_than_int.png"
|
expected = "Tests/images/imagedraw_wide_line_larger_than_int.png"
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
draw.line([(0, 0), (32768, 32768)], width=3)
|
draw.line(((0, 0), (32768, 32768)), width=3)
|
||||||
|
|
||||||
# Assert
|
# Assert
|
||||||
assert_image_similar_tofile(im, expected, 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
@ -1137,7 +1137,7 @@ def test_wide_line_larger_than_int():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"xy",
|
"xy",
|
||||||
[
|
(
|
||||||
[
|
[
|
||||||
(400, 280),
|
(400, 280),
|
||||||
(380, 280),
|
(380, 280),
|
||||||
|
@ -1214,7 +1214,7 @@ def test_wide_line_larger_than_int():
|
||||||
250,
|
250,
|
||||||
100,
|
100,
|
||||||
],
|
],
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_line_joint(xy):
|
def test_line_joint(xy):
|
||||||
im = Image.new("RGB", (500, 325))
|
im = Image.new("RGB", (500, 325))
|
||||||
|
@ -1355,8 +1355,8 @@ def test_same_color_outline(bbox):
|
||||||
s.line(x0, y0)
|
s.line(x0, y0)
|
||||||
|
|
||||||
# Begin
|
# Begin
|
||||||
for mode in ["RGB", "L"]:
|
for mode in ("RGB", "L"):
|
||||||
for fill, outline in [["red", None], ["red", "red"], ["red", "#f00"]]:
|
for fill, outline in (("red", None), ("red", "red"), ("red", "#f00")):
|
||||||
for operation, args in {
|
for operation, args in {
|
||||||
"chord": [bbox, 0, 180],
|
"chord": [bbox, 0, 180],
|
||||||
"ellipse": [bbox],
|
"ellipse": [bbox],
|
||||||
|
@ -1381,12 +1381,12 @@ def test_same_color_outline(bbox):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"n_sides, polygon_name, args",
|
"n_sides, polygon_name, args",
|
||||||
[
|
(
|
||||||
(4, "square", {}),
|
(4, "square", {}),
|
||||||
(8, "regular_octagon", {}),
|
(8, "regular_octagon", {}),
|
||||||
(4, "square_rotate_45", {"rotation": 45}),
|
(4, "square_rotate_45", {"rotation": 45}),
|
||||||
(3, "triangle_width", {"width": 5, "outline": "yellow"}),
|
(3, "triangle_width", {"width": 5, "outline": "yellow"}),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_draw_regular_polygon(n_sides, polygon_name, args):
|
def test_draw_regular_polygon(n_sides, polygon_name, args):
|
||||||
im = Image.new("RGBA", size=(W, H), color=(255, 0, 0, 0))
|
im = Image.new("RGBA", size=(W, H), color=(255, 0, 0, 0))
|
||||||
|
@ -1399,7 +1399,7 @@ def test_draw_regular_polygon(n_sides, polygon_name, args):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"n_sides, expected_vertices",
|
"n_sides, expected_vertices",
|
||||||
[
|
(
|
||||||
(3, [(28.35, 62.5), (71.65, 62.5), (50.0, 25.0)]),
|
(3, [(28.35, 62.5), (71.65, 62.5), (50.0, 25.0)]),
|
||||||
(4, [(32.32, 67.68), (67.68, 67.68), (67.68, 32.32), (32.32, 32.32)]),
|
(4, [(32.32, 67.68), (67.68, 67.68), (67.68, 32.32), (32.32, 32.32)]),
|
||||||
(
|
(
|
||||||
|
@ -1423,7 +1423,7 @@ def test_draw_regular_polygon(n_sides, polygon_name, args):
|
||||||
(25.0, 50.0),
|
(25.0, 50.0),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_compute_regular_polygon_vertices(n_sides, expected_vertices):
|
def test_compute_regular_polygon_vertices(n_sides, expected_vertices):
|
||||||
bounding_circle = (W // 2, H // 2, 25)
|
bounding_circle = (W // 2, H // 2, 25)
|
||||||
|
@ -1433,7 +1433,7 @@ def test_compute_regular_polygon_vertices(n_sides, expected_vertices):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"n_sides, bounding_circle, rotation, expected_error, error_message",
|
"n_sides, bounding_circle, rotation, expected_error, error_message",
|
||||||
[
|
(
|
||||||
(None, (50, 50, 25), 0, TypeError, "n_sides should be an int"),
|
(None, (50, 50, 25), 0, TypeError, "n_sides should be an int"),
|
||||||
(1, (50, 50, 25), 0, ValueError, "n_sides should be an int > 2"),
|
(1, (50, 50, 25), 0, ValueError, "n_sides should be an int > 2"),
|
||||||
(3, 50, 0, TypeError, "bounding_circle should be a tuple"),
|
(3, 50, 0, TypeError, "bounding_circle should be a tuple"),
|
||||||
|
@ -1473,7 +1473,7 @@ def test_compute_regular_polygon_vertices(n_sides, expected_vertices):
|
||||||
ValueError,
|
ValueError,
|
||||||
"rotation should be an int or float",
|
"rotation should be an int or float",
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_compute_regular_polygon_vertices_input_error_handling(
|
def test_compute_regular_polygon_vertices_input_error_handling(
|
||||||
n_sides, bounding_circle, rotation, expected_error, error_message
|
n_sides, bounding_circle, rotation, expected_error, error_message
|
||||||
|
@ -1484,7 +1484,7 @@ def test_compute_regular_polygon_vertices_input_error_handling(
|
||||||
|
|
||||||
|
|
||||||
def test_continuous_horizontal_edges_polygon():
|
def test_continuous_horizontal_edges_polygon():
|
||||||
xy = [
|
xy = (
|
||||||
(2, 6),
|
(2, 6),
|
||||||
(6, 6),
|
(6, 6),
|
||||||
(12, 6),
|
(12, 6),
|
||||||
|
@ -1493,7 +1493,7 @@ def test_continuous_horizontal_edges_polygon():
|
||||||
(8, 8),
|
(8, 8),
|
||||||
(4, 8),
|
(4, 8),
|
||||||
(2, 8),
|
(2, 8),
|
||||||
]
|
)
|
||||||
img, draw = create_base_image_draw((16, 16))
|
img, draw = create_base_image_draw((16, 16))
|
||||||
draw.polygon(xy, BLACK)
|
draw.polygon(xy, BLACK)
|
||||||
expected = os.path.join(IMAGES_PATH, "continuous_horizontal_edges_polygon.png")
|
expected = os.path.join(IMAGES_PATH, "continuous_horizontal_edges_polygon.png")
|
||||||
|
@ -1517,7 +1517,7 @@ def test_discontiguous_corners_polygon():
|
||||||
def test_polygon2():
|
def test_polygon2():
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
draw = ImageDraw.Draw(im)
|
draw = ImageDraw.Draw(im)
|
||||||
draw.polygon([(18, 30), (19, 31), (18, 30), (85, 30), (60, 72)], "red")
|
draw.polygon(((18, 30), (19, 31), (18, 30), (85, 30), (60, 72)), "red")
|
||||||
expected = "Tests/images/imagedraw_outline_polygon_RGB.png"
|
expected = "Tests/images/imagedraw_outline_polygon_RGB.png"
|
||||||
assert_image_similar_tofile(im, expected, 1)
|
assert_image_similar_tofile(im, expected, 1)
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ def test_big_rectangle():
|
||||||
# Test drawing a rectangle bigger than the image
|
# Test drawing a rectangle bigger than the image
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
bbox = [(-1, -1), (W + 1, H + 1)]
|
bbox = ((-1, -1), (W + 1, H + 1))
|
||||||
brush = ImageDraw2.Brush("orange")
|
brush = ImageDraw2.Brush("orange")
|
||||||
draw = ImageDraw2.Draw(im)
|
draw = ImageDraw2.Draw(im)
|
||||||
expected = "Tests/images/imagedraw_big_rectangle.png"
|
expected = "Tests/images/imagedraw_big_rectangle.png"
|
||||||
|
|
|
@ -48,7 +48,7 @@ def test_alpha(op):
|
||||||
|
|
||||||
original = _half_transparent_image()
|
original = _half_transparent_image()
|
||||||
|
|
||||||
for amount in [0, 0.5, 1.0]:
|
for amount in (0, 0.5, 1.0):
|
||||||
_check_alpha(
|
_check_alpha(
|
||||||
getattr(ImageEnhance, op)(original).enhance(amount),
|
getattr(ImageEnhance, op)(original).enhance(amount),
|
||||||
original,
|
original,
|
||||||
|
|
|
@ -34,10 +34,10 @@ def test_sanity():
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
scope="module",
|
scope="module",
|
||||||
params=[
|
params=(
|
||||||
pytest.param(ImageFont.Layout.BASIC),
|
pytest.param(ImageFont.Layout.BASIC),
|
||||||
pytest.param(ImageFont.Layout.RAQM, marks=skip_unless_feature("raqm")),
|
pytest.param(ImageFont.Layout.RAQM, marks=skip_unless_feature("raqm")),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def layout_engine(request):
|
def layout_engine(request):
|
||||||
return request.param
|
return request.param
|
||||||
|
@ -683,14 +683,14 @@ def test_variation_set_by_name(font):
|
||||||
|
|
||||||
font = ImageFont.truetype("Tests/fonts/AdobeVFPrototype.ttf", 36)
|
font = ImageFont.truetype("Tests/fonts/AdobeVFPrototype.ttf", 36)
|
||||||
_check_text(font, "Tests/images/variation_adobe.png", 11)
|
_check_text(font, "Tests/images/variation_adobe.png", 11)
|
||||||
for name in ["Bold", b"Bold"]:
|
for name in ("Bold", b"Bold"):
|
||||||
font.set_variation_by_name(name)
|
font.set_variation_by_name(name)
|
||||||
assert font.getname()[1] == "Bold"
|
assert font.getname()[1] == "Bold"
|
||||||
_check_text(font, "Tests/images/variation_adobe_name.png", 16)
|
_check_text(font, "Tests/images/variation_adobe_name.png", 16)
|
||||||
|
|
||||||
font = ImageFont.truetype("Tests/fonts/TINY5x3GX.ttf", 36)
|
font = ImageFont.truetype("Tests/fonts/TINY5x3GX.ttf", 36)
|
||||||
_check_text(font, "Tests/images/variation_tiny.png", 40)
|
_check_text(font, "Tests/images/variation_tiny.png", 40)
|
||||||
for name in ["200", b"200"]:
|
for name in ("200", b"200"):
|
||||||
font.set_variation_by_name(name)
|
font.set_variation_by_name(name)
|
||||||
assert font.getname()[1] == "200"
|
assert font.getname()[1] == "200"
|
||||||
_check_text(font, "Tests/images/variation_tiny_name.png", 40)
|
_check_text(font, "Tests/images/variation_tiny_name.png", 40)
|
||||||
|
@ -807,7 +807,7 @@ def test_anchor_invalid(font):
|
||||||
d = ImageDraw.Draw(im)
|
d = ImageDraw.Draw(im)
|
||||||
d.font = font
|
d.font = font
|
||||||
|
|
||||||
for anchor in ["", "l", "a", "lax", "sa", "xa", "lx"]:
|
for anchor in ("", "l", "a", "lax", "sa", "xa", "lx"):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
font.getmask2("hello", anchor=anchor)
|
font.getmask2("hello", anchor=anchor)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
@ -820,7 +820,7 @@ def test_anchor_invalid(font):
|
||||||
d.multiline_text((0, 0), "foo\nbar", anchor=anchor)
|
d.multiline_text((0, 0), "foo\nbar", anchor=anchor)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
d.multiline_textbbox((0, 0), "foo\nbar", anchor=anchor)
|
d.multiline_textbbox((0, 0), "foo\nbar", anchor=anchor)
|
||||||
for anchor in ["lt", "lb"]:
|
for anchor in ("lt", "lb"):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
d.multiline_text((0, 0), "foo\nbar", anchor=anchor)
|
d.multiline_text((0, 0), "foo\nbar", anchor=anchor)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
@ -830,7 +830,7 @@ def test_anchor_invalid(font):
|
||||||
@pytest.mark.parametrize("bpp", (1, 2, 4, 8))
|
@pytest.mark.parametrize("bpp", (1, 2, 4, 8))
|
||||||
def test_bitmap_font(layout_engine, bpp):
|
def test_bitmap_font(layout_engine, bpp):
|
||||||
text = "Bitmap Font"
|
text = "Bitmap Font"
|
||||||
layout_name = ["basic", "raqm"][layout_engine]
|
layout_name = ("basic", "raqm")[layout_engine]
|
||||||
target = f"Tests/images/bitmap_font_{bpp}_{layout_name}.png"
|
target = f"Tests/images/bitmap_font_{bpp}_{layout_name}.png"
|
||||||
font = ImageFont.truetype(
|
font = ImageFont.truetype(
|
||||||
f"Tests/fonts/DejaVuSans/DejaVuSans-24-{bpp}-stripped.ttf",
|
f"Tests/fonts/DejaVuSans/DejaVuSans-24-{bpp}-stripped.ttf",
|
||||||
|
@ -847,7 +847,7 @@ def test_bitmap_font(layout_engine, bpp):
|
||||||
|
|
||||||
def test_bitmap_font_stroke(layout_engine):
|
def test_bitmap_font_stroke(layout_engine):
|
||||||
text = "Bitmap Font"
|
text = "Bitmap Font"
|
||||||
layout_name = ["basic", "raqm"][layout_engine]
|
layout_name = ("basic", "raqm")[layout_engine]
|
||||||
target = f"Tests/images/bitmap_font_stroke_{layout_name}.png"
|
target = f"Tests/images/bitmap_font_stroke_{layout_name}.png"
|
||||||
font = ImageFont.truetype(
|
font = ImageFont.truetype(
|
||||||
"Tests/fonts/DejaVuSans/DejaVuSans-24-8-stripped.ttf",
|
"Tests/fonts/DejaVuSans/DejaVuSans-24-8-stripped.ttf",
|
||||||
|
@ -1035,9 +1035,7 @@ def test_render_mono_size():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
("Tests/fonts/oom-e8e927ba6c0d38274a37c1567560eb33baf74627.ttf",),
|
||||||
"Tests/fonts/oom-e8e927ba6c0d38274a37c1567560eb33baf74627.ttf",
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
def test_oom(test_file):
|
def test_oom(test_file):
|
||||||
with open(test_file, "rb") as f:
|
with open(test_file, "rb") as f:
|
||||||
|
|
|
@ -165,7 +165,7 @@ def test_arabictext_features():
|
||||||
"اللغة العربية",
|
"اللغة العربية",
|
||||||
font=ttf,
|
font=ttf,
|
||||||
fill=500,
|
fill=500,
|
||||||
features=["-fina", "-init", "-medi"],
|
features=("-fina", "-init", "-medi"),
|
||||||
)
|
)
|
||||||
|
|
||||||
target = "Tests/images/test_arabictext_features.png"
|
target = "Tests/images/test_arabictext_features.png"
|
||||||
|
@ -359,7 +359,7 @@ def test_anchor_invalid_ttb():
|
||||||
d = ImageDraw.Draw(im)
|
d = ImageDraw.Draw(im)
|
||||||
d.font = font
|
d.font = font
|
||||||
|
|
||||||
for anchor in ["", "l", "a", "lax", "xa", "la", "ls", "ld", "lx"]:
|
for anchor in ("", "l", "a", "lax", "xa", "la", "ls", "ld", "lx"):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
font.getmask2("hello", anchor=anchor, direction="ttb")
|
font.getmask2("hello", anchor=anchor, direction="ttb")
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
|
|
@ -53,9 +53,9 @@ class TestImageGrab:
|
||||||
|
|
||||||
def test_grabclipboard(self):
|
def test_grabclipboard(self):
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
subprocess.call(["screencapture", "-cx"])
|
subprocess.call(("screencapture", "-cx"))
|
||||||
elif sys.platform == "win32":
|
elif sys.platform == "win32":
|
||||||
p = subprocess.Popen(["powershell", "-command", "-"], stdin=subprocess.PIPE)
|
p = subprocess.Popen(("powershell", "-command", "-"), stdin=subprocess.PIPE)
|
||||||
p.stdin.write(
|
p.stdin.write(
|
||||||
b"""[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
|
b"""[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
|
||||||
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
|
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
|
||||||
|
@ -77,7 +77,7 @@ $bmp = New-Object Drawing.Bitmap 200, 200
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.platform != "win32", reason="Windows only")
|
@pytest.mark.skipif(sys.platform != "win32", reason="Windows only")
|
||||||
def test_grabclipboard_file(self):
|
def test_grabclipboard_file(self):
|
||||||
p = subprocess.Popen(["powershell", "-command", "-"], stdin=subprocess.PIPE)
|
p = subprocess.Popen(("powershell", "-command", "-"), stdin=subprocess.PIPE)
|
||||||
p.stdin.write(rb'Set-Clipboard -Path "Tests\images\hopper.gif"')
|
p.stdin.write(rb'Set-Clipboard -Path "Tests\images\hopper.gif"')
|
||||||
p.communicate()
|
p.communicate()
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ $bmp = New-Object Drawing.Bitmap 200, 200
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.platform != "win32", reason="Windows only")
|
@pytest.mark.skipif(sys.platform != "win32", reason="Windows only")
|
||||||
def test_grabclipboard_png(self):
|
def test_grabclipboard_png(self):
|
||||||
p = subprocess.Popen(["powershell", "-command", "-"], stdin=subprocess.PIPE)
|
p = subprocess.Popen(("powershell", "-command", "-"), stdin=subprocess.PIPE)
|
||||||
p.stdin.write(
|
p.stdin.write(
|
||||||
rb"""$bytes = [System.IO.File]::ReadAllBytes("Tests\images\hopper.png")
|
rb"""$bytes = [System.IO.File]::ReadAllBytes("Tests\images\hopper.png")
|
||||||
$ms = new-object System.IO.MemoryStream(, $bytes)
|
$ms = new-object System.IO.MemoryStream(, $bytes)
|
||||||
|
|
|
@ -26,7 +26,7 @@ def test_sanity():
|
||||||
|
|
||||||
ImageOps.autocontrast(hopper("L"), cutoff=10)
|
ImageOps.autocontrast(hopper("L"), cutoff=10)
|
||||||
ImageOps.autocontrast(hopper("L"), cutoff=(2, 10))
|
ImageOps.autocontrast(hopper("L"), cutoff=(2, 10))
|
||||||
ImageOps.autocontrast(hopper("L"), ignore=[0, 255])
|
ImageOps.autocontrast(hopper("L"), ignore=(0, 255))
|
||||||
ImageOps.autocontrast(hopper("L"), mask=hopper("L"))
|
ImageOps.autocontrast(hopper("L"), mask=hopper("L"))
|
||||||
ImageOps.autocontrast(hopper("L"), preserve_tone=True)
|
ImageOps.autocontrast(hopper("L"), preserve_tone=True)
|
||||||
|
|
||||||
|
@ -126,11 +126,11 @@ def test_pad():
|
||||||
new_im = ImageOps.pad(im, new_size)
|
new_im = ImageOps.pad(im, new_size)
|
||||||
assert new_im.size == new_size
|
assert new_im.size == new_size
|
||||||
|
|
||||||
for label, color, new_size in [
|
for label, color, new_size in (
|
||||||
("h", None, (im.width * 4, im.height * 2)),
|
("h", None, (im.width * 4, im.height * 2)),
|
||||||
("v", "#f00", (im.width * 2, im.height * 4)),
|
("v", "#f00", (im.width * 2, im.height * 4)),
|
||||||
]:
|
):
|
||||||
for i, centering in enumerate([(0, 0), (0.5, 0.5), (1, 1)]):
|
for i, centering in enumerate(((0, 0), (0.5, 0.5), (1, 1))):
|
||||||
new_im = ImageOps.pad(im, new_size, color=color, centering=centering)
|
new_im = ImageOps.pad(im, new_size, color=color, centering=centering)
|
||||||
assert new_im.size == new_size
|
assert new_im.size == new_size
|
||||||
|
|
||||||
|
@ -344,14 +344,15 @@ def test_exif_transpose():
|
||||||
exts = [".jpg"]
|
exts = [".jpg"]
|
||||||
if features.check("webp") and features.check("webp_anim"):
|
if features.check("webp") and features.check("webp_anim"):
|
||||||
exts.append(".webp")
|
exts.append(".webp")
|
||||||
|
|
||||||
for ext in exts:
|
for ext in exts:
|
||||||
with Image.open("Tests/images/hopper" + ext) as base_im:
|
with Image.open("Tests/images/hopper" + ext) as base_im:
|
||||||
|
|
||||||
def check(orientation_im):
|
def check(orientation_im):
|
||||||
for im in [
|
for im in (
|
||||||
orientation_im,
|
orientation_im,
|
||||||
orientation_im.copy(),
|
orientation_im.copy(),
|
||||||
]: # ImageFile # Image
|
): # ImageFile # Image
|
||||||
if orientation_im is base_im:
|
if orientation_im is base_im:
|
||||||
assert "exif" not in im.info
|
assert "exif" not in im.info
|
||||||
else:
|
else:
|
||||||
|
@ -449,13 +450,13 @@ def test_autocontrast_mask_real_input():
|
||||||
assert result_nomask != result
|
assert result_nomask != result
|
||||||
assert_tuple_approx_equal(
|
assert_tuple_approx_equal(
|
||||||
ImageStat.Stat(result, mask=rect_mask).median,
|
ImageStat.Stat(result, mask=rect_mask).median,
|
||||||
[195, 202, 184],
|
(195, 202, 184),
|
||||||
threshold=2,
|
threshold=2,
|
||||||
msg="autocontrast with mask pixel incorrect",
|
msg="autocontrast with mask pixel incorrect",
|
||||||
)
|
)
|
||||||
assert_tuple_approx_equal(
|
assert_tuple_approx_equal(
|
||||||
ImageStat.Stat(result_nomask).median,
|
ImageStat.Stat(result_nomask).median,
|
||||||
[119, 106, 79],
|
(119, 106, 79),
|
||||||
threshold=2,
|
threshold=2,
|
||||||
msg="autocontrast without mask pixel incorrect",
|
msg="autocontrast without mask pixel incorrect",
|
||||||
)
|
)
|
||||||
|
|
|
@ -81,7 +81,7 @@ def test_blur_accuracy(test_images):
|
||||||
i = snakes.filter(ImageFilter.GaussianBlur(0.4))
|
i = snakes.filter(ImageFilter.GaussianBlur(0.4))
|
||||||
# These pixels surrounded with pixels with 255 intensity.
|
# These pixels surrounded with pixels with 255 intensity.
|
||||||
# They must be very close to 255.
|
# They must be very close to 255.
|
||||||
for x, y, c in [
|
for x, y, c in (
|
||||||
(1, 0, 1),
|
(1, 0, 1),
|
||||||
(2, 0, 1),
|
(2, 0, 1),
|
||||||
(7, 8, 1),
|
(7, 8, 1),
|
||||||
|
@ -94,13 +94,13 @@ def test_blur_accuracy(test_images):
|
||||||
(1, 3, 0),
|
(1, 3, 0),
|
||||||
(4, 3, 2),
|
(4, 3, 2),
|
||||||
(4, 2, 2),
|
(4, 2, 2),
|
||||||
]:
|
):
|
||||||
assert i.im.getpixel((x, y))[c] >= 250
|
assert i.im.getpixel((x, y))[c] >= 250
|
||||||
# Fuzzy match.
|
|
||||||
|
|
||||||
def gp(x, y):
|
def gp(x, y):
|
||||||
return i.im.getpixel((x, y))
|
return i.im.getpixel((x, y))
|
||||||
|
|
||||||
|
# Fuzzy match.
|
||||||
assert 236 <= gp(7, 4)[0] <= 239
|
assert 236 <= gp(7, 4)[0] <= 239
|
||||||
assert 236 <= gp(7, 5)[2] <= 239
|
assert 236 <= gp(7, 5)[2] <= 239
|
||||||
assert 236 <= gp(7, 6)[2] <= 239
|
assert 236 <= gp(7, 6)[2] <= 239
|
||||||
|
|
|
@ -56,12 +56,12 @@ def test_getcolor_rgba_color_rgb_palette():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"index, palette",
|
"index, palette",
|
||||||
[
|
(
|
||||||
# Test when the palette is not full
|
# Test when the palette is not full
|
||||||
(0, ImagePalette.ImagePalette()),
|
(0, ImagePalette.ImagePalette()),
|
||||||
# Test when the palette is full
|
# Test when the palette is full
|
||||||
(255, ImagePalette.ImagePalette("RGB", list(range(256)) * 3)),
|
(255, ImagePalette.ImagePalette("RGB", list(range(256)) * 3)),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_getcolor_not_special(index, palette):
|
def test_getcolor_not_special(index, palette):
|
||||||
im = Image.new("P", (1, 1))
|
im = Image.new("P", (1, 1))
|
||||||
|
|
|
@ -102,12 +102,12 @@ def test_path_odd_number_of_coordinates(coords):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"coords, expected",
|
"coords, expected",
|
||||||
[
|
(
|
||||||
([0, 1, 2, 3], (0.0, 1.0, 2.0, 3.0)),
|
([0, 1, 2, 3], (0.0, 1.0, 2.0, 3.0)),
|
||||||
([3, 2, 1, 0], (1.0, 0.0, 3.0, 2.0)),
|
([3, 2, 1, 0], (1.0, 0.0, 3.0, 2.0)),
|
||||||
(0, (0.0, 0.0, 0.0, 0.0)),
|
(0, (0.0, 0.0, 0.0, 0.0)),
|
||||||
(1, (0.0, 0.0, 0.0, 0.0)),
|
(1, (0.0, 0.0, 0.0, 0.0)),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_getbbox(coords, expected):
|
def test_getbbox(coords, expected):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -119,7 +119,7 @@ def test_getbbox(coords, expected):
|
||||||
|
|
||||||
def test_getbbox_no_args():
|
def test_getbbox_no_args():
|
||||||
# Arrange
|
# Arrange
|
||||||
p = ImagePath.Path([0, 1, 2, 3])
|
p = ImagePath.Path((0, 1, 2, 3))
|
||||||
|
|
||||||
# Act / Assert
|
# Act / Assert
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
|
@ -128,10 +128,10 @@ def test_getbbox_no_args():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"coords, expected",
|
"coords, expected",
|
||||||
[
|
(
|
||||||
(0, []),
|
(0, []),
|
||||||
(list(range(6)), [(0.0, 3.0), (4.0, 9.0), (8.0, 15.0)]),
|
(list(range(6)), [(0.0, 3.0), (4.0, 9.0), (8.0, 15.0)]),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_map(coords, expected):
|
def test_map(coords, expected):
|
||||||
# Arrange
|
# Arrange
|
||||||
|
@ -147,7 +147,7 @@ def test_map(coords, expected):
|
||||||
|
|
||||||
def test_transform():
|
def test_transform():
|
||||||
# Arrange
|
# Arrange
|
||||||
p = ImagePath.Path([0, 1, 2, 3])
|
p = ImagePath.Path((0, 1, 2, 3))
|
||||||
theta = math.pi / 15
|
theta = math.pi / 15
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
|
@ -165,7 +165,7 @@ def test_transform():
|
||||||
|
|
||||||
def test_transform_with_wrap():
|
def test_transform_with_wrap():
|
||||||
# Arrange
|
# Arrange
|
||||||
p = ImagePath.Path([0, 1, 2, 3])
|
p = ImagePath.Path((0, 1, 2, 3))
|
||||||
theta = math.pi / 15
|
theta = math.pi / 15
|
||||||
|
|
||||||
# Act
|
# Act
|
||||||
|
|
|
@ -20,7 +20,7 @@ def test_register():
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"order",
|
"order",
|
||||||
[-1, 0],
|
(-1, 0),
|
||||||
)
|
)
|
||||||
def test_viewer_show(order):
|
def test_viewer_show(order):
|
||||||
class TestViewer(ImageShow.Viewer):
|
class TestViewer(ImageShow.Viewer):
|
||||||
|
|
|
@ -4,7 +4,7 @@ import sys
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
out = subprocess.check_output([sys.executable, "-m", "PIL"]).decode("utf-8")
|
out = subprocess.check_output((sys.executable, "-m", "PIL")).decode("utf-8")
|
||||||
lines = out.splitlines()
|
lines = out.splitlines()
|
||||||
assert lines[0] == "-" * 68
|
assert lines[0] == "-" * 68
|
||||||
assert lines[1].startswith("Pillow ")
|
assert lines[1].startswith("Pillow ")
|
||||||
|
|
|
@ -79,7 +79,7 @@ def test_parsing():
|
||||||
assert isinstance(s, PdfStream)
|
assert isinstance(s, PdfStream)
|
||||||
assert s.dictionary.Name == "value"
|
assert s.dictionary.Name == "value"
|
||||||
assert s.decode() == b"abcde"
|
assert s.decode() == b"abcde"
|
||||||
for name in ["CreationDate", "ModDate"]:
|
for name in ("CreationDate", "ModDate"):
|
||||||
for date, value in {
|
for date, value in {
|
||||||
b"20180729214124": "20180729214124",
|
b"20180729214124": "20180729214124",
|
||||||
b"D:20180729214124": "20180729214124",
|
b"D:20180729214124": "20180729214124",
|
||||||
|
|
|
@ -42,7 +42,7 @@ def helper_pickle_string(pickle, protocol, test_file, mode):
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("test_file", "test_mode"),
|
("test_file", "test_mode"),
|
||||||
[
|
(
|
||||||
("Tests/images/hopper.jpg", None),
|
("Tests/images/hopper.jpg", None),
|
||||||
("Tests/images/hopper.jpg", "L"),
|
("Tests/images/hopper.jpg", "L"),
|
||||||
("Tests/images/hopper.jpg", "PA"),
|
("Tests/images/hopper.jpg", "PA"),
|
||||||
|
@ -58,7 +58,7 @@ def helper_pickle_string(pickle, protocol, test_file, mode):
|
||||||
("Tests/images/p_trns_single.png", None),
|
("Tests/images/p_trns_single.png", None),
|
||||||
("Tests/images/pil123p.png", None),
|
("Tests/images/pil123p.png", None),
|
||||||
("Tests/images/itxt_chunks.png", None),
|
("Tests/images/itxt_chunks.png", None),
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("protocol", range(0, pickle.HIGHEST_PROTOCOL + 1))
|
@pytest.mark.parametrize("protocol", range(0, pickle.HIGHEST_PROTOCOL + 1))
|
||||||
def test_pickle_image(tmp_path, test_file, test_mode, protocol):
|
def test_pickle_image(tmp_path, test_file, test_mode, protocol):
|
||||||
|
|
|
@ -5,7 +5,7 @@ from PIL import Image
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
(
|
||||||
"Tests/images/sgi_overrun_expandrowF04.bin",
|
"Tests/images/sgi_overrun_expandrowF04.bin",
|
||||||
"Tests/images/sgi_crash.bin",
|
"Tests/images/sgi_crash.bin",
|
||||||
"Tests/images/crash-6b7f2244da6d0ae297ee0754a424213444e92778.sgi",
|
"Tests/images/crash-6b7f2244da6d0ae297ee0754a424213444e92778.sgi",
|
||||||
|
@ -17,7 +17,7 @@ from PIL import Image
|
||||||
"Tests/images/crash-b82e64d4f3f76d7465b6af535283029eda211259.sgi",
|
"Tests/images/crash-b82e64d4f3f76d7465b6af535283029eda211259.sgi",
|
||||||
"Tests/images/crash-c1b2595b8b0b92cc5f38b6635e98e3a119ade807.sgi",
|
"Tests/images/crash-c1b2595b8b0b92cc5f38b6635e98e3a119ade807.sgi",
|
||||||
"Tests/images/crash-db8bfa78b19721225425530c5946217720d7df4e.sgi",
|
"Tests/images/crash-db8bfa78b19721225425530c5946217720d7df4e.sgi",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
def test_crashes(test_file):
|
def test_crashes(test_file):
|
||||||
with open(test_file, "rb") as f:
|
with open(test_file, "rb") as f:
|
||||||
|
|
|
@ -20,7 +20,7 @@ from .helper import on_ci
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
[
|
(
|
||||||
"Tests/images/crash_1.tif",
|
"Tests/images/crash_1.tif",
|
||||||
"Tests/images/crash_2.tif",
|
"Tests/images/crash_2.tif",
|
||||||
"Tests/images/crash-2020-10-test.tif",
|
"Tests/images/crash-2020-10-test.tif",
|
||||||
|
@ -36,7 +36,7 @@ from .helper import on_ci
|
||||||
"Tests/images/crash-74d2a78403a5a59db1fb0a2b8735ac068a75f6e3.tif",
|
"Tests/images/crash-74d2a78403a5a59db1fb0a2b8735ac068a75f6e3.tif",
|
||||||
"Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif",
|
"Tests/images/crash-81154a65438ba5aaeca73fd502fa4850fbde60f8.tif",
|
||||||
"Tests/images/crash-0da013a13571cc8eb457a39fee8db18f8a3c7127.tif",
|
"Tests/images/crash-0da013a13571cc8eb457a39fee8db18f8a3c7127.tif",
|
||||||
],
|
),
|
||||||
)
|
)
|
||||||
@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data")
|
@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data")
|
||||||
@pytest.mark.filterwarnings("ignore:Metadata warning")
|
@pytest.mark.filterwarnings("ignore:Metadata warning")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user