Pillow

Форк
0
/
test_image_convert.py 
354 строки · 8.8 Кб
1
from __future__ import annotations
2

3
from pathlib import Path
4

5
import pytest
6

7
from PIL import Image
8

9
from .helper import assert_image, assert_image_equal, assert_image_similar, hopper
10

11

12
def test_sanity() -> None:
13
    def convert(im: Image.Image, mode: str) -> None:
14
        out = im.convert(mode)
15
        assert out.mode == mode
16
        assert out.size == im.size
17

18
    modes = (
19
        "1",
20
        "L",
21
        "LA",
22
        "P",
23
        "PA",
24
        "I",
25
        "F",
26
        "RGB",
27
        "RGBA",
28
        "RGBX",
29
        "CMYK",
30
        "YCbCr",
31
        "HSV",
32
    )
33

34
    for input_mode in modes:
35
        im = hopper(input_mode)
36
        for output_mode in modes:
37
            convert(im, output_mode)
38

39
        # Check 0
40
        im = Image.new(input_mode, (0, 0))
41
        for output_mode in modes:
42
            convert(im, output_mode)
43

44

45
def test_unsupported_conversion() -> None:
46
    im = hopper()
47
    with pytest.raises(ValueError):
48
        im.convert("INVALID")
49

50

51
def test_default() -> None:
52
    im = hopper("P")
53
    assert im.mode == "P"
54
    converted_im = im.convert()
55
    assert_image(converted_im, "RGB", im.size)
56
    converted_im = im.convert()
57
    assert_image(converted_im, "RGB", im.size)
58

59
    im.info["transparency"] = 0
60
    converted_im = im.convert()
61
    assert_image(converted_im, "RGBA", im.size)
62

63

64
# ref https://github.com/python-pillow/Pillow/issues/274
65

66

67
def _test_float_conversion(im: Image.Image) -> None:
68
    orig = im.getpixel((5, 5))
69
    converted = im.convert("F").getpixel((5, 5))
70
    assert orig == converted
71

72

73
def test_8bit() -> None:
74
    with Image.open("Tests/images/hopper.jpg") as im:
75
        _test_float_conversion(im.convert("L"))
76

77

78
def test_16bit() -> None:
79
    with Image.open("Tests/images/16bit.cropped.tif") as im:
80
        _test_float_conversion(im)
81

82
    for color in (65535, 65536):
83
        im = Image.new("I", (1, 1), color)
84
        im_i16 = im.convert("I;16")
85
        assert im_i16.getpixel((0, 0)) == 65535
86

87

88
def test_16bit_workaround() -> None:
89
    with Image.open("Tests/images/16bit.cropped.tif") as im:
90
        _test_float_conversion(im.convert("I"))
91

92

93
def test_opaque() -> None:
94
    alpha = hopper("P").convert("PA").getchannel("A")
95

96
    solid = Image.new("L", (128, 128), 255)
97
    assert_image_equal(alpha, solid)
98

99

100
def test_rgba_p() -> None:
101
    im = hopper("RGBA")
102
    im.putalpha(hopper("L"))
103

104
    converted = im.convert("P")
105
    comparable = converted.convert("RGBA")
106

107
    assert_image_similar(im, comparable, 20)
108

109

110
def test_rgba() -> None:
111
    with Image.open("Tests/images/transparent.png") as im:
112
        assert im.mode == "RGBA"
113

114
        assert_image_similar(im.convert("RGBa").convert("RGB"), im.convert("RGB"), 1.5)
115

116

117
def test_trns_p(tmp_path: Path) -> None:
118
    im = hopper("P")
119
    im.info["transparency"] = 0
120

121
    f = str(tmp_path / "temp.png")
122

123
    im_l = im.convert("L")
124
    assert im_l.info["transparency"] == 0
125
    im_l.save(f)
126

127
    im_rgb = im.convert("RGB")
128
    assert im_rgb.info["transparency"] == (0, 0, 0)
129
    im_rgb.save(f)
130

131

132
# ref https://github.com/python-pillow/Pillow/issues/664
133

134

135
@pytest.mark.parametrize("mode", ("LA", "PA", "RGBA"))
136
def test_trns_p_transparency(mode: str) -> None:
137
    # Arrange
138
    im = hopper("P")
139
    im.info["transparency"] = 128
140

141
    # Act
142
    converted_im = im.convert(mode)
143

144
    # Assert
145
    assert "transparency" not in converted_im.info
146
    if mode == "PA":
147
        assert converted_im.palette is not None
148
    else:
149
        # https://github.com/python-pillow/Pillow/issues/2702
150
        assert converted_im.palette is None
151

152

153
def test_trns_l(tmp_path: Path) -> None:
154
    im = hopper("L")
155
    im.info["transparency"] = 128
156

157
    f = str(tmp_path / "temp.png")
158

159
    im_la = im.convert("LA")
160
    assert "transparency" not in im_la.info
161
    im_la.save(f)
162

163
    im_rgb = im.convert("RGB")
164
    assert im_rgb.info["transparency"] == (128, 128, 128)  # undone
165
    im_rgb.save(f)
166

167
    im_p = im.convert("P")
168
    assert "transparency" in im_p.info
169
    im_p.save(f)
170

171
    im_p = im.convert("P", palette=Image.Palette.ADAPTIVE)
172
    assert "transparency" in im_p.info
173
    im_p.save(f)
174

175

176
def test_trns_RGB(tmp_path: Path) -> None:
177
    im = hopper("RGB")
178
    im.info["transparency"] = im.getpixel((0, 0))
179

180
    f = str(tmp_path / "temp.png")
181

182
    im_l = im.convert("L")
183
    assert im_l.info["transparency"] == im_l.getpixel((0, 0))  # undone
184
    im_l.save(f)
185

186
    im_la = im.convert("LA")
187
    assert "transparency" not in im_la.info
188
    im_la.save(f)
189

190
    im_la = im.convert("La")
191
    assert "transparency" not in im_la.info
192
    assert im_la.getpixel((0, 0)) == (0, 0)
193

194
    im_p = im.convert("P")
195
    assert "transparency" in im_p.info
196
    im_p.save(f)
197

198
    im_rgba = im.convert("RGBA")
199
    assert "transparency" not in im_rgba.info
200
    im_rgba.save(f)
201

202
    im_rgba = im.convert("RGBa")
203
    assert "transparency" not in im_rgba.info
204
    assert im_rgba.getpixel((0, 0)) == (0, 0, 0, 0)
205

206
    im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE)
207
    assert "transparency" not in im_p.info
208
    im_p.save(f)
209

210
    im = Image.new("RGB", (1, 1))
211
    im.info["transparency"] = im.getpixel((0, 0))
212
    im_p = im.convert("P", palette=Image.Palette.ADAPTIVE)
213
    assert im_p.info["transparency"] == im_p.getpixel((0, 0))
214
    im_p.save(f)
215

216

217
@pytest.mark.parametrize("convert_mode", ("L", "LA", "I"))
218
def test_l_macro_rounding(convert_mode: str) -> None:
219
    for mode in ("P", "PA"):
220
        im = Image.new(mode, (1, 1))
221
        assert im.palette is not None
222
        im.palette.getcolor((0, 1, 2))
223

224
        converted_im = im.convert(convert_mode)
225
        px = converted_im.load()
226
        assert px is not None
227
        converted_color = px[0, 0]
228
        if convert_mode == "LA":
229
            assert isinstance(converted_color, tuple)
230
            converted_color = converted_color[0]
231
        assert converted_color == 1
232

233

234
def test_gif_with_rgba_palette_to_p() -> None:
235
    # See https://github.com/python-pillow/Pillow/issues/2433
236
    with Image.open("Tests/images/hopper.gif") as im:
237
        im.info["transparency"] = 255
238
        im.load()
239
        assert im.palette.mode == "RGB"
240
        im_p = im.convert("P")
241

242
    # Should not raise ValueError: unrecognized raw mode
243
    im_p.load()
244

245

246
def test_p_la() -> None:
247
    im = hopper("RGBA")
248
    alpha = hopper("L")
249
    im.putalpha(alpha)
250

251
    comparable = im.convert("P").convert("LA").getchannel("A")
252

253
    assert_image_similar(alpha, comparable, 5)
254

255

256
def test_p2pa_alpha() -> None:
257
    with Image.open("Tests/images/tiny.png") as im:
258
        assert im.mode == "P"
259

260
        im_pa = im.convert("PA")
261
    assert im_pa.mode == "PA"
262

263
    im_a = im_pa.getchannel("A")
264
    for x in range(4):
265
        alpha = 255 if x > 1 else 0
266
        for y in range(4):
267
            assert im_a.getpixel((x, y)) == alpha
268

269

270
def test_p2pa_palette() -> None:
271
    with Image.open("Tests/images/tiny.png") as im:
272
        im_pa = im.convert("PA")
273
    assert im_pa.getpalette() == im.getpalette()
274

275

276
def test_matrix_illegal_conversion() -> None:
277
    # Arrange
278
    im = hopper("CMYK")
279
    # fmt: off
280
    matrix = (
281
        0.412453, 0.357580, 0.180423, 0,
282
        0.212671, 0.715160, 0.072169, 0,
283
        0.019334, 0.119193, 0.950227, 0)
284
    # fmt: on
285
    assert im.mode != "RGB"
286

287
    # Act / Assert
288
    with pytest.raises(ValueError):
289
        im.convert(mode="CMYK", matrix=matrix)
290

291

292
def test_matrix_wrong_mode() -> None:
293
    # Arrange
294
    im = hopper("L")
295
    # fmt: off
296
    matrix = (
297
        0.412453, 0.357580, 0.180423, 0,
298
        0.212671, 0.715160, 0.072169, 0,
299
        0.019334, 0.119193, 0.950227, 0)
300
    # fmt: on
301
    assert im.mode == "L"
302

303
    # Act / Assert
304
    with pytest.raises(ValueError):
305
        im.convert(mode="L", matrix=matrix)
306

307

308
@pytest.mark.parametrize("mode", ("RGB", "L"))
309
def test_matrix_xyz(mode: str) -> None:
310
    # Arrange
311
    im = hopper("RGB")
312
    im.info["transparency"] = (255, 0, 0)
313
    # fmt: off
314
    matrix = (
315
        0.412453, 0.357580, 0.180423, 0,
316
        0.212671, 0.715160, 0.072169, 0,
317
        0.019334, 0.119193, 0.950227, 0)
318
    # fmt: on
319
    assert im.mode == "RGB"
320

321
    # Act
322
    # Convert an RGB image to the CIE XYZ colour space
323
    converted_im = im.convert(mode=mode, matrix=matrix)
324

325
    # Assert
326
    assert converted_im.mode == mode
327
    assert converted_im.size == im.size
328
    with Image.open("Tests/images/hopper-XYZ.png") as target:
329
        if converted_im.mode == "RGB":
330
            assert_image_similar(converted_im, target, 3)
331
            assert converted_im.info["transparency"] == (105, 54, 4)
332
        else:
333
            assert_image_similar(converted_im, target.getchannel(0), 1)
334
            assert converted_im.info["transparency"] == 105
335

336

337
def test_matrix_identity() -> None:
338
    # Arrange
339
    im = hopper("RGB")
340
    # fmt: off
341
    identity_matrix = (
342
        1, 0, 0, 0,
343
        0, 1, 0, 0,
344
        0, 0, 1, 0)
345
    # fmt: on
346
    assert im.mode == "RGB"
347

348
    # Act
349
    # Convert with an identity matrix
350
    converted_im = im.convert(mode="RGB", matrix=identity_matrix)
351

352
    # Assert
353
    # No change
354
    assert_image_equal(converted_im, im)
355

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.