Format with Black

This commit is contained in:
Hugo 2019-06-13 18:54:24 +03:00
parent f87821e010
commit 77f946d8bc
40 changed files with 1097 additions and 926 deletions

View File

@ -4,22 +4,24 @@ import sys
from PIL import Image, features, ImageDraw, ImageFont from PIL import Image, features, ImageDraw, ImageFont
@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or macOS") @unittest.skipIf(sys.platform.startswith("win32"), "requires Unix or macOS")
class TestTTypeFontLeak(PillowLeakTestCase): class TestTTypeFontLeak(PillowLeakTestCase):
# fails at iteration 3 in master # fails at iteration 3 in master
iterations = 10 iterations = 10
mem_limit = 4096 # k mem_limit = 4096 # k
def _test_font(self, font): def _test_font(self, font):
im = Image.new('RGB', (255, 255), 'white') im = Image.new("RGB", (255, 255), "white")
draw = ImageDraw.ImageDraw(im) draw = ImageDraw.ImageDraw(im)
self._test_leak(lambda: draw.text((0, 0), "some text "*1024, # ~10k self._test_leak(
font=font, fill="black")) lambda: draw.text(
(0, 0), "some text " * 1024, font=font, fill="black" # ~10k
)
)
@unittest.skipIf(not features.check('freetype2'), @unittest.skipIf(not features.check("freetype2"), "Test requires freetype2")
"Test requires freetype2")
def test_leak(self): def test_leak(self):
ttype = ImageFont.truetype('Tests/fonts/FreeMono.ttf', 20) ttype = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 20)
self._test_font(ttype) self._test_font(ttype)

View File

@ -12,7 +12,6 @@ message = "hello, world"
class TestFontPcf(PillowTestCase): class TestFontPcf(PillowTestCase):
def setUp(self): def setUp(self):
if "zip_encoder" not in codecs or "zip_decoder" not in codecs: if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
self.skipTest("zlib support not available") self.skipTest("zlib support not available")
@ -25,15 +24,15 @@ class TestFontPcf(PillowTestCase):
self.assertEqual(len([_f for _f in font.glyph if _f]), 223) self.assertEqual(len([_f for _f in font.glyph if _f]), 223)
tempname = self.tempfile("temp.pil") tempname = self.tempfile("temp.pil")
self.addCleanup(self.delete_tempfile, tempname[:-4]+'.pbm') self.addCleanup(self.delete_tempfile, tempname[:-4] + ".pbm")
font.save(tempname) font.save(tempname)
with Image.open(tempname.replace('.pil', '.pbm')) as loaded: with Image.open(tempname.replace(".pil", ".pbm")) as loaded:
with Image.open('Tests/fonts/10x20.pbm') as target: with Image.open("Tests/fonts/10x20.pbm") as target:
self.assert_image_equal(loaded, target) self.assert_image_equal(loaded, target)
with open(tempname, 'rb') as f_loaded: with open(tempname, "rb") as f_loaded:
with open('Tests/fonts/10x20.pil', 'rb') as f_target: with open("Tests/fonts/10x20.pil", "rb") as f_target:
self.assertEqual(f_loaded.read(), f_target.read()) self.assertEqual(f_loaded.read(), f_target.read())
return tempname return tempname
@ -49,8 +48,8 @@ class TestFontPcf(PillowTestCase):
font = ImageFont.load(tempname) font = ImageFont.load(tempname)
im = Image.new("L", (130, 30), "white") im = Image.new("L", (130, 30), "white")
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), message, 'black', font=font) draw.text((0, 0), message, "black", font=font)
with Image.open('Tests/images/test_draw_pbm_target.png') as target: with Image.open("Tests/images/test_draw_pbm_target.png") as target:
self.assert_image_similar(im, target, 0) self.assert_image_similar(im, target, 0)
def test_textsize(self): def test_textsize(self):
@ -61,8 +60,8 @@ class TestFontPcf(PillowTestCase):
self.assertEqual(dy, 20) self.assertEqual(dy, 20)
self.assertIn(dx, (0, 10)) self.assertIn(dx, (0, 10))
for l in range(len(message)): for l in range(len(message)):
msg = message[:l+1] msg = message[: l + 1]
self.assertEqual(font.getsize(msg), (len(msg)*10, 20)) self.assertEqual(font.getsize(msg), (len(msg) * 10, 20))
def _test_high_characters(self, message): def _test_high_characters(self, message):
tempname = self.save_font() tempname = self.save_font()
@ -70,12 +69,12 @@ class TestFontPcf(PillowTestCase):
im = Image.new("L", (750, 30), "white") im = Image.new("L", (750, 30), "white")
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
draw.text((0, 0), message, "black", font=font) draw.text((0, 0), message, "black", font=font)
with Image.open('Tests/images/high_ascii_chars.png') as target: with Image.open("Tests/images/high_ascii_chars.png") as target:
self.assert_image_similar(im, target, 0) self.assert_image_similar(im, target, 0)
def test_high_characters(self): def test_high_characters(self):
message = "".join(chr(i+1) for i in range(140, 232)) message = "".join(chr(i + 1) for i in range(140, 232))
self._test_high_characters(message) self._test_high_characters(message)
# accept bytes instances in Py3. # accept bytes instances in Py3.
if py3: if py3:
self._test_high_characters(message.encode('latin1')) self._test_high_characters(message.encode("latin1"))

View File

@ -8,19 +8,18 @@ import itertools
class TestFormatHSV(PillowTestCase): class TestFormatHSV(PillowTestCase):
def int_to_float(self, i): def int_to_float(self, i):
return float(i)/255.0 return float(i) / 255.0
def str_to_float(self, i): def str_to_float(self, i):
return float(ord(i))/255.0 return float(ord(i)) / 255.0
def tuple_to_ints(self, tp): def tuple_to_ints(self, tp):
x, y, z = tp x, y, z = tp
return int(x*255.0), int(y*255.0), int(z*255.0) return int(x * 255.0), int(y * 255.0), int(z * 255.0)
def test_sanity(self): def test_sanity(self):
Image.new('HSV', (100, 100)) Image.new("HSV", (100, 100))
def wedge(self): def wedge(self):
w = Image._wedge() w = Image._wedge()
@ -28,7 +27,7 @@ class TestFormatHSV(PillowTestCase):
(px, h) = w.size (px, h) = w.size
r = Image.new('L', (px*3, h)) r = Image.new("L", (px * 3, h))
g = r.copy() g = r.copy()
b = r.copy() b = r.copy()
@ -36,12 +35,12 @@ class TestFormatHSV(PillowTestCase):
r.paste(w90, (px, 0)) r.paste(w90, (px, 0))
g.paste(w90, (0, 0)) g.paste(w90, (0, 0))
g.paste(w, (2*px, 0)) g.paste(w, (2 * px, 0))
b.paste(w, (px, 0)) b.paste(w, (px, 0))
b.paste(w90, (2*px, 0)) b.paste(w90, (2 * px, 0))
img = Image.merge('RGB', (r, g, b)) img = Image.merge("RGB", (r, g, b))
return img return img
@ -55,77 +54,101 @@ class TestFormatHSV(PillowTestCase):
else: else:
conv_func = self.str_to_float conv_func = self.str_to_float
if hasattr(itertools, 'izip'): if hasattr(itertools, "izip"):
iter_helper = itertools.izip iter_helper = itertools.izip
else: else:
iter_helper = itertools.zip_longest iter_helper = itertools.zip_longest
converted = [self.tuple_to_ints(func(conv_func(_r), conv_func(_g), converted = [
conv_func(_b))) self.tuple_to_ints(func(conv_func(_r), conv_func(_g), conv_func(_b)))
for (_r, _g, _b) in iter_helper(r.tobytes(), g.tobytes(), for (_r, _g, _b) in iter_helper(r.tobytes(), g.tobytes(), b.tobytes())
b.tobytes())] ]
if py3: if py3:
new_bytes = b''.join(bytes(chr(h)+chr(s)+chr(v), 'latin-1') for ( new_bytes = b"".join(
h, s, v) in converted) bytes(chr(h) + chr(s) + chr(v), "latin-1") for (h, s, v) in converted
)
else: else:
new_bytes = b''.join(chr(h)+chr(s)+chr(v) for ( new_bytes = b"".join(chr(h) + chr(s) + chr(v) for (h, s, v) in converted)
h, s, v) in converted)
hsv = Image.frombytes(mode, r.size, new_bytes) hsv = Image.frombytes(mode, r.size, new_bytes)
return hsv return hsv
def to_hsv_colorsys(self, im): def to_hsv_colorsys(self, im):
return self.to_xxx_colorsys(im, colorsys.rgb_to_hsv, 'HSV') return self.to_xxx_colorsys(im, colorsys.rgb_to_hsv, "HSV")
def to_rgb_colorsys(self, im): def to_rgb_colorsys(self, im):
return self.to_xxx_colorsys(im, colorsys.hsv_to_rgb, 'RGB') return self.to_xxx_colorsys(im, colorsys.hsv_to_rgb, "RGB")
def test_wedge(self): def test_wedge(self):
src = self.wedge().resize((3*32, 32), Image.BILINEAR) src = self.wedge().resize((3 * 32, 32), Image.BILINEAR)
im = src.convert('HSV') im = src.convert("HSV")
comparable = self.to_hsv_colorsys(src) comparable = self.to_hsv_colorsys(src)
self.assert_image_similar(im.getchannel(0), comparable.getchannel(0), self.assert_image_similar(
1, "Hue conversion is wrong") im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
self.assert_image_similar(im.getchannel(1), comparable.getchannel(1), )
1, "Saturation conversion is wrong") self.assert_image_similar(
self.assert_image_similar(im.getchannel(2), comparable.getchannel(2), im.getchannel(1),
1, "Value conversion is wrong") comparable.getchannel(1),
1,
"Saturation conversion is wrong",
)
self.assert_image_similar(
im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong"
)
comparable = src comparable = src
im = im.convert('RGB') im = im.convert("RGB")
self.assert_image_similar(im.getchannel(0), comparable.getchannel(0), self.assert_image_similar(
3, "R conversion is wrong") im.getchannel(0), comparable.getchannel(0), 3, "R conversion is wrong"
self.assert_image_similar(im.getchannel(1), comparable.getchannel(1), )
3, "G conversion is wrong") self.assert_image_similar(
self.assert_image_similar(im.getchannel(2), comparable.getchannel(2), im.getchannel(1), comparable.getchannel(1), 3, "G conversion is wrong"
3, "B conversion is wrong") )
self.assert_image_similar(
im.getchannel(2), comparable.getchannel(2), 3, "B conversion is wrong"
)
def test_convert(self): def test_convert(self):
im = hopper('RGB').convert('HSV') im = hopper("RGB").convert("HSV")
comparable = self.to_hsv_colorsys(hopper('RGB')) comparable = self.to_hsv_colorsys(hopper("RGB"))
self.assert_image_similar(im.getchannel(0), comparable.getchannel(0), self.assert_image_similar(
1, "Hue conversion is wrong") im.getchannel(0), comparable.getchannel(0), 1, "Hue conversion is wrong"
self.assert_image_similar(im.getchannel(1), comparable.getchannel(1), )
1, "Saturation conversion is wrong") self.assert_image_similar(
self.assert_image_similar(im.getchannel(2), comparable.getchannel(2), im.getchannel(1),
1, "Value conversion is wrong") comparable.getchannel(1),
1,
"Saturation conversion is wrong",
)
self.assert_image_similar(
im.getchannel(2), comparable.getchannel(2), 1, "Value conversion is wrong"
)
def test_hsv_to_rgb(self): def test_hsv_to_rgb(self):
comparable = self.to_hsv_colorsys(hopper('RGB')) comparable = self.to_hsv_colorsys(hopper("RGB"))
converted = comparable.convert('RGB') converted = comparable.convert("RGB")
comparable = self.to_rgb_colorsys(comparable) comparable = self.to_rgb_colorsys(comparable)
self.assert_image_similar(converted.getchannel(0), self.assert_image_similar(
comparable.getchannel(0), converted.getchannel(0),
3, "R conversion is wrong") comparable.getchannel(0),
self.assert_image_similar(converted.getchannel(1), 3,
comparable.getchannel(1), "R conversion is wrong",
3, "G conversion is wrong") )
self.assert_image_similar(converted.getchannel(2), self.assert_image_similar(
comparable.getchannel(2), converted.getchannel(1),
3, "B conversion is wrong") comparable.getchannel(1),
3,
"G conversion is wrong",
)
self.assert_image_similar(
converted.getchannel(2),
comparable.getchannel(2),
3,
"B conversion is wrong",
)

View File

@ -4,15 +4,14 @@ from PIL import Image
class TestFormatLab(PillowTestCase): class TestFormatLab(PillowTestCase):
def test_white(self): def test_white(self):
i = Image.open('Tests/images/lab.tif') i = Image.open("Tests/images/lab.tif")
i.load() i.load()
self.assertEqual(i.mode, 'LAB') self.assertEqual(i.mode, "LAB")
self.assertEqual(i.getbands(), ('L', 'A', 'B')) self.assertEqual(i.getbands(), ("L", "A", "B"))
k = i.getpixel((0, 0)) k = i.getpixel((0, 0))
self.assertEqual(k, (255, 128, 128)) self.assertEqual(k, (255, 128, 128))
@ -21,14 +20,14 @@ class TestFormatLab(PillowTestCase):
a = i.getdata(1) a = i.getdata(1)
b = i.getdata(2) b = i.getdata(2)
self.assertEqual(list(L), [255]*100) self.assertEqual(list(L), [255] * 100)
self.assertEqual(list(a), [128]*100) self.assertEqual(list(a), [128] * 100)
self.assertEqual(list(b), [128]*100) self.assertEqual(list(b), [128] * 100)
def test_green(self): def test_green(self):
# l= 50 (/100), a = -100 (-128 .. 128) b=0 in PS # l= 50 (/100), a = -100 (-128 .. 128) b=0 in PS
# == RGB: 0, 152, 117 # == RGB: 0, 152, 117
i = Image.open('Tests/images/lab-green.tif') i = Image.open("Tests/images/lab-green.tif")
k = i.getpixel((0, 0)) k = i.getpixel((0, 0))
self.assertEqual(k, (128, 28, 128)) self.assertEqual(k, (128, 28, 128))
@ -36,7 +35,7 @@ class TestFormatLab(PillowTestCase):
def test_red(self): def test_red(self):
# l= 50 (/100), a = 100 (-128 .. 128) b=0 in PS # l= 50 (/100), a = 100 (-128 .. 128) b=0 in PS
# == RGB: 255, 0, 124 # == RGB: 255, 0, 124
i = Image.open('Tests/images/lab-red.tif') i = Image.open("Tests/images/lab-red.tif")
k = i.getpixel((0, 0)) k = i.getpixel((0, 0))
self.assertEqual(k, (128, 228, 128)) self.assertEqual(k, (128, 228, 128))

View File

@ -8,37 +8,54 @@ import shutil
class TestImage(PillowTestCase): class TestImage(PillowTestCase):
def test_image_modes_success(self): def test_image_modes_success(self):
for mode in [ for mode in [
'1', 'P', 'PA', "1",
'L', 'LA', 'La', "P",
'F', 'I', 'I;16', 'I;16L', 'I;16B', 'I;16N', "PA",
'RGB', 'RGBX', 'RGBA', 'RGBa', "L",
'CMYK', 'YCbCr', 'LAB', 'HSV', "LA",
"La",
"F",
"I",
"I;16",
"I;16L",
"I;16B",
"I;16N",
"RGB",
"RGBX",
"RGBA",
"RGBa",
"CMYK",
"YCbCr",
"LAB",
"HSV",
]: ]:
Image.new(mode, (1, 1)) Image.new(mode, (1, 1))
def test_image_modes_fail(self): def test_image_modes_fail(self):
for mode in [ for mode in [
'', 'bad', 'very very long', "",
'BGR;15', 'BGR;16', 'BGR;24', 'BGR;32' "bad",
"very very long",
"BGR;15",
"BGR;16",
"BGR;24",
"BGR;32",
]: ]:
with self.assertRaises(ValueError) as e: with self.assertRaises(ValueError) as e:
Image.new(mode, (1, 1)) Image.new(mode, (1, 1))
self.assertEqual(str(e.exception), 'unrecognized image mode') self.assertEqual(str(e.exception), "unrecognized image mode")
def test_sanity(self): def test_sanity(self):
im = Image.new("L", (100, 100)) im = Image.new("L", (100, 100))
self.assertEqual( self.assertEqual(repr(im)[:45], "<PIL.Image.Image image mode=L size=100x100 at")
repr(im)[:45], "<PIL.Image.Image image mode=L size=100x100 at")
self.assertEqual(im.mode, "L") self.assertEqual(im.mode, "L")
self.assertEqual(im.size, (100, 100)) self.assertEqual(im.size, (100, 100))
im = Image.new("RGB", (100, 100)) im = Image.new("RGB", (100, 100))
self.assertEqual( self.assertEqual(repr(im)[:45], "<PIL.Image.Image image mode=RGB size=100x100 ")
repr(im)[:45], "<PIL.Image.Image image mode=RGB size=100x100 ")
self.assertEqual(im.mode, "RGB") self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (100, 100)) self.assertEqual(im.size, (100, 100))
@ -64,10 +81,12 @@ class TestImage(PillowTestCase):
def test_invalid_image(self): def test_invalid_image(self):
if py3: if py3:
import io import io
im = io.BytesIO(b'')
im = io.BytesIO(b"")
else: else:
import StringIO import StringIO
im = StringIO.StringIO('')
im = StringIO.StringIO("")
self.assertRaises(IOError, Image.open, im) self.assertRaises(IOError, Image.open, im)
def test_bad_mode(self): def test_bad_mode(self):
@ -76,6 +95,7 @@ class TestImage(PillowTestCase):
@unittest.skipUnless(Image.HAS_PATHLIB, "requires pathlib/pathlib2") @unittest.skipUnless(Image.HAS_PATHLIB, "requires pathlib/pathlib2")
def test_pathlib(self): def test_pathlib(self):
from PIL.Image import Path from PIL.Image import Path
im = Image.open(Path("Tests/images/multipage-mmap.tiff")) im = Image.open(Path("Tests/images/multipage-mmap.tiff"))
self.assertEqual(im.mode, "P") self.assertEqual(im.mode, "P")
self.assertEqual(im.size, (10, 10)) self.assertEqual(im.size, (10, 10))
@ -95,6 +115,7 @@ class TestImage(PillowTestCase):
class FP(object): class FP(object):
def write(a, b): def write(a, b):
pass pass
fp = FP() fp = FP()
fp.name = temp_file fp.name = temp_file
@ -105,9 +126,10 @@ class TestImage(PillowTestCase):
# see #1460, pathlib support breaks tempfile.TemporaryFile on py27 # see #1460, pathlib support breaks tempfile.TemporaryFile on py27
# Will error out on save on 3.0.0 # Will error out on save on 3.0.0
import tempfile import tempfile
im = hopper() im = hopper()
with tempfile.TemporaryFile() as fp: with tempfile.TemporaryFile() as fp:
im.save(fp, 'JPEG') im.save(fp, "JPEG")
fp.seek(0) fp.seek(0)
reloaded = Image.open(fp) reloaded = Image.open(fp)
self.assert_image_similar(im, reloaded, 20) self.assert_image_similar(im, reloaded, 20)
@ -127,8 +149,9 @@ class TestImage(PillowTestCase):
im.paste(0, (0, 0, 100, 100)) im.paste(0, (0, 0, 100, 100))
self.assertFalse(im.readonly) self.assertFalse(im.readonly)
@unittest.skipIf(sys.platform.startswith('win32'), @unittest.skipIf(
"Test requires opening tempfile twice") sys.platform.startswith("win32"), "Test requires opening tempfile twice"
)
def test_readonly_save(self): def test_readonly_save(self):
temp_file = self.tempfile("temp.bmp") temp_file = self.tempfile("temp.bmp")
shutil.copy("Tests/images/rgb32bf-rgba.bmp", temp_file) shutil.copy("Tests/images/rgb32bf-rgba.bmp", temp_file)
@ -149,7 +172,7 @@ class TestImage(PillowTestCase):
def test_comparison_with_other_type(self): def test_comparison_with_other_type(self):
# Arrange # Arrange
item = Image.new('RGB', (25, 25), '#000') item = Image.new("RGB", (25, 25), "#000")
num = 12 num = 12
# Act/Assert # Act/Assert
@ -167,8 +190,8 @@ class TestImage(PillowTestCase):
im = im._expand(xmargin) im = im._expand(xmargin)
# Assert # Assert
self.assertEqual(im.size[0], orig_size[0] + 2*xmargin) self.assertEqual(im.size[0], orig_size[0] + 2 * xmargin)
self.assertEqual(im.size[1], orig_size[1] + 2*xmargin) self.assertEqual(im.size[1], orig_size[1] + 2 * xmargin)
def test_expand_xy(self): def test_expand_xy(self):
# Arrange # Arrange
@ -181,32 +204,32 @@ class TestImage(PillowTestCase):
im = im._expand(xmargin, ymargin) im = im._expand(xmargin, ymargin)
# Assert # Assert
self.assertEqual(im.size[0], orig_size[0] + 2*xmargin) self.assertEqual(im.size[0], orig_size[0] + 2 * xmargin)
self.assertEqual(im.size[1], orig_size[1] + 2*ymargin) self.assertEqual(im.size[1], orig_size[1] + 2 * ymargin)
def test_getbands(self): def test_getbands(self):
# Assert # Assert
self.assertEqual(hopper('RGB').getbands(), ('R', 'G', 'B')) self.assertEqual(hopper("RGB").getbands(), ("R", "G", "B"))
self.assertEqual(hopper('YCbCr').getbands(), ('Y', 'Cb', 'Cr')) self.assertEqual(hopper("YCbCr").getbands(), ("Y", "Cb", "Cr"))
def test_getchannel_wrong_params(self): def test_getchannel_wrong_params(self):
im = hopper() im = hopper()
self.assertRaises(ValueError, im.getchannel, -1) self.assertRaises(ValueError, im.getchannel, -1)
self.assertRaises(ValueError, im.getchannel, 3) self.assertRaises(ValueError, im.getchannel, 3)
self.assertRaises(ValueError, im.getchannel, 'Z') self.assertRaises(ValueError, im.getchannel, "Z")
self.assertRaises(ValueError, im.getchannel, '1') self.assertRaises(ValueError, im.getchannel, "1")
def test_getchannel(self): def test_getchannel(self):
im = hopper('YCbCr') im = hopper("YCbCr")
Y, Cb, Cr = im.split() Y, Cb, Cr = im.split()
self.assert_image_equal(Y, im.getchannel(0)) self.assert_image_equal(Y, im.getchannel(0))
self.assert_image_equal(Y, im.getchannel('Y')) self.assert_image_equal(Y, im.getchannel("Y"))
self.assert_image_equal(Cb, im.getchannel(1)) self.assert_image_equal(Cb, im.getchannel(1))
self.assert_image_equal(Cb, im.getchannel('Cb')) self.assert_image_equal(Cb, im.getchannel("Cb"))
self.assert_image_equal(Cr, im.getchannel(2)) self.assert_image_equal(Cr, im.getchannel(2))
self.assert_image_equal(Cr, im.getchannel('Cr')) self.assert_image_equal(Cr, im.getchannel("Cr"))
def test_getbbox(self): def test_getbbox(self):
# Arrange # Arrange
@ -220,8 +243,8 @@ class TestImage(PillowTestCase):
def test_ne(self): def test_ne(self):
# Arrange # Arrange
im1 = Image.new('RGB', (25, 25), 'black') im1 = Image.new("RGB", (25, 25), "black")
im2 = Image.new('RGB', (25, 25), 'white') im2 = Image.new("RGB", (25, 25), "white")
# Act / Assert # Act / Assert
self.assertNotEqual(im1, im2) self.assertNotEqual(im1, im2)
@ -231,20 +254,23 @@ class TestImage(PillowTestCase):
# Arrange # Arrange
from PIL import ImageDraw from PIL import ImageDraw
expected_colors = sorted([ expected_colors = sorted(
(1122, (128, 127, 0, 255)), [
(1089, (0, 255, 0, 255)), (1122, (128, 127, 0, 255)),
(3300, (255, 0, 0, 255)), (1089, (0, 255, 0, 255)),
(1156, (170, 85, 0, 192)), (3300, (255, 0, 0, 255)),
(1122, (0, 255, 0, 128)), (1156, (170, 85, 0, 192)),
(1122, (255, 0, 0, 128)), (1122, (0, 255, 0, 128)),
(1089, (0, 255, 0, 0))]) (1122, (255, 0, 0, 128)),
(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))
draw = ImageDraw.Draw(dst) draw = ImageDraw.Draw(dst)
draw.rectangle((0, 33, 100, 66), fill=(0, 255, 0, 128)) draw.rectangle((0, 33, 100, 66), fill=(0, 255, 0, 128))
draw.rectangle((0, 67, 100, 100), fill=(0, 255, 0, 0)) draw.rectangle((0, 67, 100, 100), fill=(0, 255, 0, 0))
src = Image.new('RGBA', size=(100, 100), color=(255, 0, 0, 255)) src = Image.new("RGBA", size=(100, 100), color=(255, 0, 0, 255))
draw = ImageDraw.Draw(src) draw = ImageDraw.Draw(src)
draw.rectangle((33, 0, 66, 100), fill=(255, 0, 0, 128)) draw.rectangle((33, 0, 66, 100), fill=(255, 0, 0, 128))
draw.rectangle((67, 0, 100, 100), fill=(255, 0, 0, 0)) draw.rectangle((67, 0, 100, 100), fill=(255, 0, 0, 0))
@ -257,10 +283,10 @@ class TestImage(PillowTestCase):
self.assertEqual(img_colors, expected_colors) self.assertEqual(img_colors, expected_colors)
def test_alpha_inplace(self): def test_alpha_inplace(self):
src = Image.new('RGBA', (128, 128), 'blue') src = Image.new("RGBA", (128, 128), "blue")
over = Image.new('RGBA', (128, 128), 'red') over = Image.new("RGBA", (128, 128), "red")
mask = hopper('L') mask = hopper("L")
over.putalpha(mask) over.putalpha(mask)
target = Image.alpha_composite(src, over) target = Image.alpha_composite(src, over)
@ -273,41 +299,36 @@ class TestImage(PillowTestCase):
# with offset down to right # with offset down to right
offset = src.copy() offset = src.copy()
offset.alpha_composite(over, (64, 64)) offset.alpha_composite(over, (64, 64))
self.assert_image_equal(offset.crop((64, 64, 127, 127)), self.assert_image_equal(
target.crop((0, 0, 63, 63))) offset.crop((64, 64, 127, 127)), target.crop((0, 0, 63, 63))
)
self.assertEqual(offset.size, (128, 128)) self.assertEqual(offset.size, (128, 128))
# offset and crop # offset and crop
box = src.copy() box = src.copy()
box.alpha_composite(over, (64, 64), (0, 0, 32, 32)) box.alpha_composite(over, (64, 64), (0, 0, 32, 32))
self.assert_image_equal(box.crop((64, 64, 96, 96)), self.assert_image_equal(box.crop((64, 64, 96, 96)), target.crop((0, 0, 32, 32)))
target.crop((0, 0, 32, 32))) self.assert_image_equal(box.crop((96, 96, 128, 128)), src.crop((0, 0, 32, 32)))
self.assert_image_equal(box.crop((96, 96, 128, 128)),
src.crop((0, 0, 32, 32)))
self.assertEqual(box.size, (128, 128)) self.assertEqual(box.size, (128, 128))
# source point # source point
source = src.copy() source = src.copy()
source.alpha_composite(over, (32, 32), (32, 32, 96, 96)) source.alpha_composite(over, (32, 32), (32, 32, 96, 96))
self.assert_image_equal(source.crop((32, 32, 96, 96)), self.assert_image_equal(
target.crop((32, 32, 96, 96))) source.crop((32, 32, 96, 96)), target.crop((32, 32, 96, 96))
)
self.assertEqual(source.size, (128, 128)) self.assertEqual(source.size, (128, 128))
# errors # errors
self.assertRaises(ValueError, self.assertRaises(ValueError, source.alpha_composite, over, "invalid source")
source.alpha_composite, over, "invalid source") self.assertRaises(
self.assertRaises(ValueError, ValueError, source.alpha_composite, over, (0, 0), "invalid destination"
source.alpha_composite, over, (0, 0), )
"invalid destination") self.assertRaises(ValueError, source.alpha_composite, over, 0)
self.assertRaises(ValueError, self.assertRaises(ValueError, source.alpha_composite, over, (0, 0), 0)
source.alpha_composite, over, 0) self.assertRaises(ValueError, source.alpha_composite, over, (0, -1))
self.assertRaises(ValueError, self.assertRaises(ValueError, source.alpha_composite, over, (0, 0), (0, -1))
source.alpha_composite, over, (0, 0), 0)
self.assertRaises(ValueError,
source.alpha_composite, over, (0, -1))
self.assertRaises(ValueError,
source.alpha_composite, over, (0, 0), (0, -1))
def test_registered_extensions_uninitialized(self): def test_registered_extensions_uninitialized(self):
# Arrange # Arrange
@ -328,14 +349,14 @@ class TestImage(PillowTestCase):
def test_registered_extensions(self): def test_registered_extensions(self):
# Arrange # Arrange
# Open an image to trigger plugin registration # Open an image to trigger plugin registration
Image.open('Tests/images/rgb.jpg') Image.open("Tests/images/rgb.jpg")
# Act # Act
extensions = Image.registered_extensions() extensions = Image.registered_extensions()
# Assert # Assert
self.assertTrue(extensions) self.assertTrue(extensions)
for ext in ['.cur', '.icns', '.tif', '.tiff']: for ext in [".cur", ".icns", ".tif", ".tiff"]:
self.assertIn(ext, extensions) self.assertIn(ext, extensions)
def test_effect_mandelbrot(self): def test_effect_mandelbrot(self):
@ -349,7 +370,7 @@ class TestImage(PillowTestCase):
# Assert # Assert
self.assertEqual(im.size, (512, 512)) self.assertEqual(im.size, (512, 512))
im2 = Image.open('Tests/images/effect_mandelbrot.png') im2 = Image.open("Tests/images/effect_mandelbrot.png")
self.assert_image_equal(im, im2) self.assert_image_equal(im, im2)
def test_effect_mandelbrot_bad_arguments(self): def test_effect_mandelbrot_bad_arguments(self):
@ -361,9 +382,7 @@ class TestImage(PillowTestCase):
quality = 1 quality = 1
# Act/Assert # Act/Assert
self.assertRaises( self.assertRaises(ValueError, Image.effect_mandelbrot, size, extent, quality)
ValueError,
Image.effect_mandelbrot, size, extent, quality)
def test_effect_noise(self): def test_effect_noise(self):
# Arrange # Arrange
@ -393,32 +412,32 @@ class TestImage(PillowTestCase):
# Assert # Assert
self.assertEqual(im.size, (128, 128)) self.assertEqual(im.size, (128, 128))
im3 = Image.open('Tests/images/effect_spread.png') im3 = Image.open("Tests/images/effect_spread.png")
self.assert_image_similar(im2, im3, 110) self.assert_image_similar(im2, im3, 110)
def test_check_size(self): def test_check_size(self):
# Checking that the _check_size function throws value errors # Checking that the _check_size function throws value errors
# when we want it to. # when we want it to.
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
Image.new('RGB', 0) # not a tuple Image.new("RGB", 0) # not a tuple
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
Image.new('RGB', (0,)) # Tuple too short Image.new("RGB", (0,)) # Tuple too short
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
Image.new('RGB', (-1, -1)) # w,h < 0 Image.new("RGB", (-1, -1)) # w,h < 0
# this should pass with 0 sized images, #2259 # this should pass with 0 sized images, #2259
im = Image.new('L', (0, 0)) im = Image.new("L", (0, 0))
self.assertEqual(im.size, (0, 0)) self.assertEqual(im.size, (0, 0))
im = Image.new('L', (0, 100)) im = Image.new("L", (0, 100))
self.assertEqual(im.size, (0, 100)) self.assertEqual(im.size, (0, 100))
im = Image.new('L', (100, 0)) im = Image.new("L", (100, 0))
self.assertEqual(im.size, (100, 0)) self.assertEqual(im.size, (100, 0))
self.assertTrue(Image.new('RGB', (1, 1))) self.assertTrue(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])
self.assertIsInstance(i.size, tuple) self.assertIsInstance(i.size, tuple)
def test_storage_neg(self): def test_storage_neg(self):
@ -428,7 +447,7 @@ class TestImage(PillowTestCase):
# Storage.c, rather than the size check above # Storage.c, rather than the size check above
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
Image.core.fill('RGB', (2, -2), (0, 0, 0)) Image.core.fill("RGB", (2, -2), (0, 0, 0))
def test_offset_not_implemented(self): def test_offset_not_implemented(self):
# Arrange # Arrange
@ -445,8 +464,7 @@ class TestImage(PillowTestCase):
wrong_mode = "RGB" wrong_mode = "RGB"
# Act / Assert # Act / Assert
self.assertRaises(ValueError, self.assertRaises(ValueError, Image.linear_gradient, wrong_mode)
Image.linear_gradient, wrong_mode)
def test_linear_gradient(self): def test_linear_gradient(self):
@ -470,8 +488,7 @@ class TestImage(PillowTestCase):
wrong_mode = "RGB" wrong_mode = "RGB"
# Act / Assert # Act / Assert
self.assertRaises(ValueError, self.assertRaises(ValueError, Image.radial_gradient, wrong_mode)
Image.radial_gradient, wrong_mode)
def test_radial_gradient(self): def test_radial_gradient(self):
@ -514,11 +531,11 @@ class TestImage(PillowTestCase):
def test__new(self): def test__new(self):
from PIL import ImagePalette from PIL import ImagePalette
im = hopper('RGB') im = hopper("RGB")
im_p = hopper('P') im_p = hopper("P")
blank_p = Image.new('P', (10, 10)) blank_p = Image.new("P", (10, 10))
blank_pa = Image.new('PA', (10, 10)) blank_pa = Image.new("PA", (10, 10))
blank_p.palette = None blank_p.palette = None
blank_pa.palette = None blank_pa.palette = None
@ -528,8 +545,7 @@ class TestImage(PillowTestCase):
self.assertEqual(new_im.size, im.size) self.assertEqual(new_im.size, im.size)
self.assertEqual(new_im.info, base_image.info) self.assertEqual(new_im.info, base_image.info)
if palette_result is not None: if palette_result is not None:
self.assertEqual(new_im.palette.tobytes(), self.assertEqual(new_im.palette.tobytes(), palette_result.tobytes())
palette_result.tobytes())
else: else:
self.assertIsNone(new_im.palette) self.assertIsNone(new_im.palette)
@ -540,9 +556,9 @@ class TestImage(PillowTestCase):
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)
@ -551,7 +567,7 @@ class TestImage(PillowTestCase):
def test_no_resource_warning_on_save(self): def test_no_resource_warning_on_save(self):
# https://github.com/python-pillow/Pillow/issues/835 # https://github.com/python-pillow/Pillow/issues/835
# Arrange # Arrange
test_file = 'Tests/images/hopper.png' test_file = "Tests/images/hopper.png"
temp_file = self.tempfile("temp.jpg") temp_file = self.tempfile("temp.jpg")
# Act/Assert # Act/Assert
@ -560,9 +576,11 @@ class TestImage(PillowTestCase):
def test_load_on_nonexclusive_multiframe(self): def test_load_on_nonexclusive_multiframe(self):
with open("Tests/images/frozenpond.mpo", "rb") as fp: with open("Tests/images/frozenpond.mpo", "rb") as fp:
def act(fp): def act(fp):
im = Image.open(fp) im = Image.open(fp)
im.load() im.load()
act(fp) act(fp)
with Image.open(fp) as im: with Image.open(fp) as im:
@ -582,19 +600,22 @@ def mock_encode(*args):
class TestRegistry(PillowTestCase): class TestRegistry(PillowTestCase):
def test_encode_registry(self): def test_encode_registry(self):
Image.register_encoder('MOCK', mock_encode) Image.register_encoder("MOCK", mock_encode)
self.assertIn('MOCK', Image.ENCODERS) self.assertIn("MOCK", Image.ENCODERS)
enc = Image._getencoder('RGB', 'MOCK', ('args',), extra=('extra',)) enc = Image._getencoder("RGB", "MOCK", ("args",), extra=("extra",))
self.assertIsInstance(enc, MockEncoder) self.assertIsInstance(enc, MockEncoder)
self.assertEqual(enc.args, ('RGB', 'args', 'extra')) self.assertEqual(enc.args, ("RGB", "args", "extra"))
def test_encode_registry_fail(self): def test_encode_registry_fail(self):
self.assertRaises(IOError, Image._getencoder, 'RGB', self.assertRaises(
'DoesNotExist', IOError,
('args',), Image._getencoder,
extra=('extra',)) "RGB",
"DoesNotExist",
("args",),
extra=("extra",),
)

View File

@ -70,11 +70,10 @@ class TestImagePutPixel(AccessTest):
width, height = im1.size width, height = im1.size
self.assertEqual(im1.getpixel((0, 0)), im1.getpixel((-width, -height))) self.assertEqual(im1.getpixel((0, 0)), im1.getpixel((-width, -height)))
self.assertEqual(im1.getpixel((-1, -1)), self.assertEqual(im1.getpixel((-1, -1)), im1.getpixel((width - 1, height - 1)))
im1.getpixel((width-1, height-1)))
for y in range(-1, -im1.size[1]-1, -1): for y in range(-1, -im1.size[1] - 1, -1):
for x in range(-1, -im1.size[0]-1, -1): for x in range(-1, -im1.size[0] - 1, -1):
pos = x, y pos = x, y
im2.putpixel(pos, im1.getpixel(pos)) im2.putpixel(pos, im1.getpixel(pos))
@ -83,8 +82,8 @@ class TestImagePutPixel(AccessTest):
im2 = Image.new(im1.mode, im1.size, 0) im2 = Image.new(im1.mode, im1.size, 0)
im2.readonly = 1 im2.readonly = 1
for y in range(-1, -im1.size[1]-1, -1): for y in range(-1, -im1.size[1] - 1, -1):
for x in range(-1, -im1.size[0]-1, -1): for x in range(-1, -im1.size[0] - 1, -1):
pos = x, y pos = x, y
im2.putpixel(pos, im1.getpixel(pos)) im2.putpixel(pos, im1.getpixel(pos))
@ -96,8 +95,8 @@ class TestImagePutPixel(AccessTest):
pix1 = im1.load() pix1 = im1.load()
pix2 = im2.load() pix2 = im2.load()
for y in range(-1, -im1.size[1]-1, -1): for y in range(-1, -im1.size[1] - 1, -1):
for x in range(-1, -im1.size[0]-1, -1): for x in range(-1, -im1.size[0] - 1, -1):
pix2[x, y] = pix1[x, y] pix2[x, y] = pix1[x, y]
self.assert_image_equal(im1, im2) self.assert_image_equal(im1, im2)
@ -120,15 +119,19 @@ class TestImageGetPixel(AccessTest):
im = Image.new(mode, (1, 1), None) im = Image.new(mode, (1, 1), None)
im.putpixel((0, 0), c) im.putpixel((0, 0), c)
self.assertEqual( self.assertEqual(
im.getpixel((0, 0)), c, im.getpixel((0, 0)),
"put/getpixel roundtrip failed for mode %s, color %s" % (mode, c)) c,
"put/getpixel roundtrip failed for mode %s, color %s" % (mode, c),
)
# check putpixel negative index # check putpixel negative index
im.putpixel((-1, -1), c) im.putpixel((-1, -1), c)
self.assertEqual( self.assertEqual(
im.getpixel((-1, -1)), c, im.getpixel((-1, -1)),
c,
"put/getpixel roundtrip negative index failed" "put/getpixel roundtrip negative index failed"
" for mode %s, color %s" % (mode, c)) " for mode %s, color %s" % (mode, c),
)
# Check 0 # Check 0
im = Image.new(mode, (0, 0), None) im = Image.new(mode, (0, 0), None)
@ -145,13 +148,17 @@ class TestImageGetPixel(AccessTest):
# check initial color # check initial color
im = Image.new(mode, (1, 1), c) im = Image.new(mode, (1, 1), c)
self.assertEqual( self.assertEqual(
im.getpixel((0, 0)), c, im.getpixel((0, 0)),
"initial color failed for mode %s, color %s " % (mode, c)) c,
"initial color failed for mode %s, color %s " % (mode, c),
)
# check initial color negative index # check initial color negative index
self.assertEqual( self.assertEqual(
im.getpixel((-1, -1)), c, im.getpixel((-1, -1)),
c,
"initial color failed with negative index" "initial color failed with negative index"
"for mode %s, color %s " % (mode, c)) "for mode %s, color %s " % (mode, c),
)
# Check 0 # Check 0
im = Image.new(mode, (0, 0), c) im = Image.new(mode, (0, 0), c)
@ -162,18 +169,32 @@ class TestImageGetPixel(AccessTest):
im.getpixel((-1, -1)) im.getpixel((-1, -1))
def test_basic(self): def test_basic(self):
for mode in ("1", "L", "LA", "I", "I;16", "I;16B", "F", for mode in (
"P", "PA", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr"): "1",
"L",
"LA",
"I",
"I;16",
"I;16B",
"F",
"P",
"PA",
"RGB",
"RGBA",
"RGBX",
"CMYK",
"YCbCr",
):
self.check(mode) self.check(mode)
def test_signedness(self): def test_signedness(self):
# see https://github.com/python-pillow/Pillow/issues/452 # see https://github.com/python-pillow/Pillow/issues/452
# pixelaccess is using signed int* instead of uint* # pixelaccess is using signed int* instead of uint*
for mode in ("I;16", "I;16B"): for mode in ("I;16", "I;16B"):
self.check(mode, 2**15-1) self.check(mode, 2 ** 15 - 1)
self.check(mode, 2**15) self.check(mode, 2 ** 15)
self.check(mode, 2**15+1) self.check(mode, 2 ** 15 + 1)
self.check(mode, 2**16-1) self.check(mode, 2 ** 16 - 1)
def test_p_putpixel_rgb_rgba(self): def test_p_putpixel_rgb_rgba(self):
for color in [(255, 0, 0), (255, 0, 0, 255)]: for color in [(255, 0, 0), (255, 0, 0, 255)]:
@ -210,29 +231,30 @@ class TestCffi(AccessTest):
self.assertEqual(access[(x, y)], caccess[(x, y)]) self.assertEqual(access[(x, y)], caccess[(x, y)])
# Access an out-of-range pixel # Access an out-of-range pixel
self.assertRaises(ValueError, self.assertRaises(
lambda: access[(access.xsize+1, access.ysize+1)]) ValueError, lambda: access[(access.xsize + 1, access.ysize + 1)]
)
def test_get_vs_c(self): def test_get_vs_c(self):
rgb = hopper('RGB') rgb = hopper("RGB")
rgb.load() rgb.load()
self._test_get_access(rgb) self._test_get_access(rgb)
self._test_get_access(hopper('RGBA')) self._test_get_access(hopper("RGBA"))
self._test_get_access(hopper('L')) self._test_get_access(hopper("L"))
self._test_get_access(hopper('LA')) self._test_get_access(hopper("LA"))
self._test_get_access(hopper('1')) self._test_get_access(hopper("1"))
self._test_get_access(hopper('P')) self._test_get_access(hopper("P"))
# self._test_get_access(hopper('PA')) # PA -- how do I make a PA image? # self._test_get_access(hopper('PA')) # PA -- how do I make a PA image?
self._test_get_access(hopper('F')) self._test_get_access(hopper("F"))
im = Image.new('I;16', (10, 10), 40000) im = Image.new("I;16", (10, 10), 40000)
self._test_get_access(im) self._test_get_access(im)
im = Image.new('I;16L', (10, 10), 40000) im = Image.new("I;16L", (10, 10), 40000)
self._test_get_access(im) self._test_get_access(im)
im = Image.new('I;16B', (10, 10), 40000) im = Image.new("I;16B", (10, 10), 40000)
self._test_get_access(im) self._test_get_access(im)
im = Image.new('I', (10, 10), 40000) im = Image.new("I", (10, 10), 40000)
self._test_get_access(im) self._test_get_access(im)
# These don't actually appear to be modes that I can actually make, # These don't actually appear to be modes that I can actually make,
# as unpack sets them directly into the I mode. # as unpack sets them directly into the I mode.
@ -261,25 +283,25 @@ class TestCffi(AccessTest):
access[(0, 0)] = color access[(0, 0)] = color
def test_set_vs_c(self): def test_set_vs_c(self):
rgb = hopper('RGB') rgb = hopper("RGB")
rgb.load() rgb.load()
self._test_set_access(rgb, (255, 128, 0)) self._test_set_access(rgb, (255, 128, 0))
self._test_set_access(hopper('RGBA'), (255, 192, 128, 0)) self._test_set_access(hopper("RGBA"), (255, 192, 128, 0))
self._test_set_access(hopper('L'), 128) self._test_set_access(hopper("L"), 128)
self._test_set_access(hopper('LA'), (128, 128)) self._test_set_access(hopper("LA"), (128, 128))
self._test_set_access(hopper('1'), 255) self._test_set_access(hopper("1"), 255)
self._test_set_access(hopper('P'), 128) self._test_set_access(hopper("P"), 128)
# self._test_set_access(i, (128, 128)) #PA -- undone how to make # self._test_set_access(i, (128, 128)) #PA -- undone how to make
self._test_set_access(hopper('F'), 1024.0) self._test_set_access(hopper("F"), 1024.0)
im = Image.new('I;16', (10, 10), 40000) im = Image.new("I;16", (10, 10), 40000)
self._test_set_access(im, 45000) self._test_set_access(im, 45000)
im = Image.new('I;16L', (10, 10), 40000) im = Image.new("I;16L", (10, 10), 40000)
self._test_set_access(im, 45000) self._test_set_access(im, 45000)
im = Image.new('I;16B', (10, 10), 40000) im = Image.new("I;16B", (10, 10), 40000)
self._test_set_access(im, 45000) self._test_set_access(im, 45000)
im = Image.new('I', (10, 10), 40000) im = Image.new("I", (10, 10), 40000)
self._test_set_access(im, 45000) self._test_set_access(im, 45000)
# im = Image.new('I;32L', (10, 10), -(2**10)) # im = Image.new('I;32L', (10, 10), -(2**10))
# self._test_set_access(im, -(2**13)+1) # self._test_set_access(im, -(2**13)+1)
@ -295,7 +317,7 @@ class TestCffi(AccessTest):
for _ in range(10): for _ in range(10):
# Do not save references to the image, only to the access object # Do not save references to the image, only to the access object
px = Image.new('L', (size, 1), 0).load() px = Image.new("L", (size, 1), 0).load()
for i in range(size): for i in range(size):
# pixels can contain garbage if image is released # pixels can contain garbage if image is released
self.assertEqual(px[i, 0], 0) self.assertEqual(px[i, 0], 0)
@ -309,16 +331,18 @@ class TestCffi(AccessTest):
class TestEmbeddable(unittest.TestCase): class TestEmbeddable(unittest.TestCase):
@unittest.skipIf(not sys.platform.startswith('win32') or @unittest.skipIf(
on_appveyor(), not sys.platform.startswith("win32") or on_appveyor(),
"Failing on AppVeyor when run from subprocess, not from shell") "Failing on AppVeyor when run from subprocess, not from shell",
)
def test_embeddable(self): def test_embeddable(self):
import subprocess import subprocess
import ctypes import ctypes
from distutils import ccompiler, sysconfig from distutils import ccompiler, sysconfig
with open('embed_pil.c', 'w') as fh: with open("embed_pil.c", "w") as fh:
fh.write(""" fh.write(
"""
#include "Python.h" #include "Python.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -345,24 +369,27 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
""" % sys.prefix.replace('\\', '\\\\')) """
% sys.prefix.replace("\\", "\\\\")
)
compiler = ccompiler.new_compiler() compiler = ccompiler.new_compiler()
compiler.add_include_dir(sysconfig.get_python_inc()) compiler.add_include_dir(sysconfig.get_python_inc())
libdir = (sysconfig.get_config_var('LIBDIR') or libdir = sysconfig.get_config_var(
sysconfig.get_python_inc().replace('include', 'libs')) "LIBDIR"
) or sysconfig.get_python_inc().replace("include", "libs")
print(libdir) print(libdir)
compiler.add_library_dir(libdir) compiler.add_library_dir(libdir)
objects = compiler.compile(['embed_pil.c']) objects = compiler.compile(["embed_pil.c"])
compiler.link_executable(objects, 'embed_pil') compiler.link_executable(objects, "embed_pil")
env = os.environ.copy() env = os.environ.copy()
env["PATH"] = sys.prefix + ';' + env["PATH"] env["PATH"] = sys.prefix + ";" + env["PATH"]
# do not display the Windows Error Reporting dialog # do not display the Windows Error Reporting dialog
ctypes.windll.kernel32.SetErrorMode(0x0002) ctypes.windll.kernel32.SetErrorMode(0x0002)
process = subprocess.Popen(['embed_pil.exe'], env=env) process = subprocess.Popen(["embed_pil.exe"], env=env)
process.communicate() process.communicate()
self.assertEqual(process.returncode, 0) self.assertEqual(process.returncode, 0)

View File

@ -6,28 +6,25 @@ im = hopper().resize((128, 100))
class TestImageArray(PillowTestCase): class TestImageArray(PillowTestCase):
def test_toarray(self): def test_toarray(self):
def test(mode): def test(mode):
ai = im.convert(mode).__array_interface__ ai = im.convert(mode).__array_interface__
return ai['version'], ai["shape"], ai["typestr"], len(ai["data"]) return ai["version"], ai["shape"], ai["typestr"], len(ai["data"])
# self.assertEqual(test("1"), (3, (100, 128), '|b1', 1600)) # self.assertEqual(test("1"), (3, (100, 128), '|b1', 1600))
self.assertEqual(test("L"), (3, (100, 128), '|u1', 12800)) self.assertEqual(test("L"), (3, (100, 128), "|u1", 12800))
# FIXME: wrong? # FIXME: wrong?
self.assertEqual(test("I"), (3, (100, 128), self.assertEqual(test("I"), (3, (100, 128), Image._ENDIAN + "i4", 51200))
Image._ENDIAN + 'i4', 51200))
# FIXME: wrong? # FIXME: wrong?
self.assertEqual(test("F"), (3, (100, 128), self.assertEqual(test("F"), (3, (100, 128), Image._ENDIAN + "f4", 51200))
Image._ENDIAN + 'f4', 51200))
self.assertEqual(test("LA"), (3, (100, 128, 2), '|u1', 25600)) self.assertEqual(test("LA"), (3, (100, 128, 2), "|u1", 25600))
self.assertEqual(test("RGB"), (3, (100, 128, 3), '|u1', 38400)) self.assertEqual(test("RGB"), (3, (100, 128, 3), "|u1", 38400))
self.assertEqual(test("RGBA"), (3, (100, 128, 4), '|u1', 51200)) self.assertEqual(test("RGBA"), (3, (100, 128, 4), "|u1", 51200))
self.assertEqual(test("RGBX"), (3, (100, 128, 4), '|u1', 51200)) self.assertEqual(test("RGBX"), (3, (100, 128, 4), "|u1", 51200))
def test_fromarray(self): def test_fromarray(self):
class Wrapper(object): class Wrapper(object):
""" Class with API matching Image.fromarray """ """ Class with API matching Image.fromarray """

View File

@ -4,16 +4,26 @@ from PIL import Image
class TestImageConvert(PillowTestCase): class TestImageConvert(PillowTestCase):
def test_sanity(self): def test_sanity(self):
def convert(im, mode): def convert(im, mode):
out = im.convert(mode) out = im.convert(mode)
self.assertEqual(out.mode, mode) self.assertEqual(out.mode, mode)
self.assertEqual(out.size, im.size) self.assertEqual(out.size, im.size)
modes = ("1", "L", "LA", "P", "PA", "I", "F", modes = (
"RGB", "RGBA", "RGBX", "CMYK", "YCbCr") "1",
"L",
"LA",
"P",
"PA",
"I",
"F",
"RGB",
"RGBA",
"RGBX",
"CMYK",
"YCbCr",
)
for mode in modes: for mode in modes:
im = hopper(mode) im = hopper(mode)
@ -38,162 +48,159 @@ class TestImageConvert(PillowTestCase):
def _test_float_conversion(self, im): def _test_float_conversion(self, im):
orig = im.getpixel((5, 5)) orig = im.getpixel((5, 5))
converted = im.convert('F').getpixel((5, 5)) converted = im.convert("F").getpixel((5, 5))
self.assertEqual(orig, converted) self.assertEqual(orig, converted)
def test_8bit(self): def test_8bit(self):
im = Image.open('Tests/images/hopper.jpg') im = Image.open("Tests/images/hopper.jpg")
self._test_float_conversion(im.convert('L')) self._test_float_conversion(im.convert("L"))
def test_16bit(self): def test_16bit(self):
im = Image.open('Tests/images/16bit.cropped.tif') im = Image.open("Tests/images/16bit.cropped.tif")
self._test_float_conversion(im) self._test_float_conversion(im)
def test_16bit_workaround(self): def test_16bit_workaround(self):
im = Image.open('Tests/images/16bit.cropped.tif') im = Image.open("Tests/images/16bit.cropped.tif")
self._test_float_conversion(im.convert('I')) self._test_float_conversion(im.convert("I"))
def test_rgba_p(self): def test_rgba_p(self):
im = hopper('RGBA') im = hopper("RGBA")
im.putalpha(hopper('L')) im.putalpha(hopper("L"))
converted = im.convert('P') converted = im.convert("P")
comparable = converted.convert('RGBA') comparable = converted.convert("RGBA")
self.assert_image_similar(im, comparable, 20) self.assert_image_similar(im, comparable, 20)
def test_trns_p(self): def test_trns_p(self):
im = hopper('P') im = hopper("P")
im.info['transparency'] = 0 im.info["transparency"] = 0
f = self.tempfile('temp.png') f = self.tempfile("temp.png")
im_l = im.convert('L') im_l = im.convert("L")
self.assertEqual(im_l.info['transparency'], 0) # undone self.assertEqual(im_l.info["transparency"], 0) # undone
im_l.save(f) im_l.save(f)
im_rgb = im.convert('RGB') im_rgb = im.convert("RGB")
self.assertEqual(im_rgb.info['transparency'], (0, 0, 0)) # undone self.assertEqual(im_rgb.info["transparency"], (0, 0, 0)) # undone
im_rgb.save(f) im_rgb.save(f)
# ref https://github.com/python-pillow/Pillow/issues/664 # ref https://github.com/python-pillow/Pillow/issues/664
def test_trns_p_rgba(self): def test_trns_p_rgba(self):
# Arrange # Arrange
im = hopper('P') im = hopper("P")
im.info['transparency'] = 128 im.info["transparency"] = 128
# Act # Act
im_rgba = im.convert('RGBA') im_rgba = im.convert("RGBA")
# Assert # Assert
self.assertNotIn('transparency', im_rgba.info) self.assertNotIn("transparency", im_rgba.info)
# https://github.com/python-pillow/Pillow/issues/2702 # https://github.com/python-pillow/Pillow/issues/2702
self.assertIsNone(im_rgba.palette) self.assertIsNone(im_rgba.palette)
def test_trns_l(self): def test_trns_l(self):
im = hopper('L') im = hopper("L")
im.info['transparency'] = 128 im.info["transparency"] = 128
f = self.tempfile('temp.png') f = self.tempfile("temp.png")
im_rgb = im.convert('RGB') im_rgb = im.convert("RGB")
self.assertEqual(im_rgb.info['transparency'], self.assertEqual(im_rgb.info["transparency"], (128, 128, 128)) # undone
(128, 128, 128)) # undone
im_rgb.save(f) im_rgb.save(f)
im_p = im.convert('P') im_p = im.convert("P")
self.assertIn('transparency', im_p.info) self.assertIn("transparency", im_p.info)
im_p.save(f) im_p.save(f)
im_p = self.assert_warning( im_p = self.assert_warning(UserWarning, im.convert, "P", palette=Image.ADAPTIVE)
UserWarning, self.assertNotIn("transparency", im_p.info)
im.convert, 'P', palette=Image.ADAPTIVE)
self.assertNotIn('transparency', im_p.info)
im_p.save(f) im_p.save(f)
def test_trns_RGB(self): def test_trns_RGB(self):
im = hopper('RGB') im = hopper("RGB")
im.info['transparency'] = im.getpixel((0, 0)) im.info["transparency"] = im.getpixel((0, 0))
f = self.tempfile('temp.png') f = self.tempfile("temp.png")
im_l = im.convert('L') im_l = im.convert("L")
self.assertEqual(im_l.info['transparency'], self.assertEqual(im_l.info["transparency"], im_l.getpixel((0, 0))) # undone
im_l.getpixel((0, 0))) # undone
im_l.save(f) im_l.save(f)
im_p = im.convert('P') im_p = im.convert("P")
self.assertIn('transparency', im_p.info) self.assertIn("transparency", im_p.info)
im_p.save(f) im_p.save(f)
im_rgba = im.convert('RGBA') im_rgba = im.convert("RGBA")
self.assertNotIn('transparency', im_rgba.info) self.assertNotIn("transparency", im_rgba.info)
im_rgba.save(f) im_rgba.save(f)
im_p = self.assert_warning( im_p = self.assert_warning(UserWarning, im.convert, "P", palette=Image.ADAPTIVE)
UserWarning, self.assertNotIn("transparency", im_p.info)
im.convert, 'P', palette=Image.ADAPTIVE)
self.assertNotIn('transparency', im_p.info)
im_p.save(f) im_p.save(f)
def test_gif_with_rgba_palette_to_p(self): def test_gif_with_rgba_palette_to_p(self):
# See https://github.com/python-pillow/Pillow/issues/2433 # See https://github.com/python-pillow/Pillow/issues/2433
im = Image.open('Tests/images/hopper.gif') im = Image.open("Tests/images/hopper.gif")
im.info['transparency'] = 255 im.info["transparency"] = 255
im.load() im.load()
self.assertEqual(im.palette.mode, 'RGBA') self.assertEqual(im.palette.mode, "RGBA")
im_p = im.convert('P') im_p = im.convert("P")
# Should not raise ValueError: unrecognized raw mode # Should not raise ValueError: unrecognized raw mode
im_p.load() im_p.load()
def test_p_la(self): def test_p_la(self):
im = hopper('RGBA') im = hopper("RGBA")
alpha = hopper('L') alpha = hopper("L")
im.putalpha(alpha) im.putalpha(alpha)
comparable = im.convert('P').convert('LA').getchannel('A') comparable = im.convert("P").convert("LA").getchannel("A")
self.assert_image_similar(alpha, comparable, 5) self.assert_image_similar(alpha, comparable, 5)
def test_matrix_illegal_conversion(self): def test_matrix_illegal_conversion(self):
# Arrange # Arrange
im = hopper('CMYK') im = hopper("CMYK")
# fmt: off
matrix = ( matrix = (
0.412453, 0.357580, 0.180423, 0, 0.412453, 0.357580, 0.180423, 0,
0.212671, 0.715160, 0.072169, 0, 0.212671, 0.715160, 0.072169, 0,
0.019334, 0.119193, 0.950227, 0) 0.019334, 0.119193, 0.950227, 0)
self.assertNotEqual(im.mode, 'RGB') # fmt: on
self.assertNotEqual(im.mode, "RGB")
# Act / Assert # Act / Assert
self.assertRaises(ValueError, self.assertRaises(ValueError, im.convert, mode="CMYK", matrix=matrix)
im.convert, mode='CMYK', matrix=matrix)
def test_matrix_wrong_mode(self): def test_matrix_wrong_mode(self):
# Arrange # Arrange
im = hopper('L') im = hopper("L")
# fmt: off
matrix = ( matrix = (
0.412453, 0.357580, 0.180423, 0, 0.412453, 0.357580, 0.180423, 0,
0.212671, 0.715160, 0.072169, 0, 0.212671, 0.715160, 0.072169, 0,
0.019334, 0.119193, 0.950227, 0) 0.019334, 0.119193, 0.950227, 0)
self.assertEqual(im.mode, 'L') # fmt: on
self.assertEqual(im.mode, "L")
# Act / Assert # Act / Assert
self.assertRaises(ValueError, self.assertRaises(ValueError, im.convert, mode="L", matrix=matrix)
im.convert, mode='L', matrix=matrix)
def test_matrix_xyz(self): def test_matrix_xyz(self):
def matrix_convert(mode): def matrix_convert(mode):
# Arrange # Arrange
im = hopper('RGB') im = hopper("RGB")
im.info['transparency'] = (255, 0, 0) im.info["transparency"] = (255, 0, 0)
# fmt: off
matrix = ( matrix = (
0.412453, 0.357580, 0.180423, 0, 0.412453, 0.357580, 0.180423, 0,
0.212671, 0.715160, 0.072169, 0, 0.212671, 0.715160, 0.072169, 0,
0.019334, 0.119193, 0.950227, 0) 0.019334, 0.119193, 0.950227, 0)
self.assertEqual(im.mode, 'RGB') # fmt: on
self.assertEqual(im.mode, "RGB")
# Act # Act
# Convert an RGB image to the CIE XYZ colour space # Convert an RGB image to the CIE XYZ colour space
@ -202,31 +209,31 @@ class TestImageConvert(PillowTestCase):
# Assert # Assert
self.assertEqual(converted_im.mode, mode) self.assertEqual(converted_im.mode, mode)
self.assertEqual(converted_im.size, im.size) self.assertEqual(converted_im.size, im.size)
target = Image.open('Tests/images/hopper-XYZ.png') target = Image.open("Tests/images/hopper-XYZ.png")
if converted_im.mode == 'RGB': if converted_im.mode == "RGB":
self.assert_image_similar(converted_im, target, 3) self.assert_image_similar(converted_im, target, 3)
self.assertEqual(converted_im.info['transparency'], self.assertEqual(converted_im.info["transparency"], (105, 54, 4))
(105, 54, 4))
else: else:
self.assert_image_similar(converted_im, self.assert_image_similar(converted_im, target.getchannel(0), 1)
target.getchannel(0), 1) self.assertEqual(converted_im.info["transparency"], 105)
self.assertEqual(converted_im.info['transparency'], 105)
matrix_convert('RGB') matrix_convert("RGB")
matrix_convert('L') matrix_convert("L")
def test_matrix_identity(self): def test_matrix_identity(self):
# Arrange # Arrange
im = hopper('RGB') im = hopper("RGB")
# fmt: off
identity_matrix = ( identity_matrix = (
1, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0) 0, 0, 1, 0)
self.assertEqual(im.mode, 'RGB') # fmt: on
self.assertEqual(im.mode, "RGB")
# Act # Act
# Convert with an identity matrix # Convert with an identity matrix
converted_im = im.convert(mode='RGB', matrix=identity_matrix) converted_im = im.convert(mode="RGB", matrix=identity_matrix)
# Assert # Assert
# No change # No change

View File

@ -6,7 +6,6 @@ import copy
class TestImageCopy(PillowTestCase): class TestImageCopy(PillowTestCase):
def test_copy(self): def test_copy(self):
croppedCoordinates = (10, 10, 20, 20) croppedCoordinates = (10, 10, 20, 20)
croppedSize = (10, 10) croppedSize = (10, 10)
@ -36,7 +35,7 @@ class TestImageCopy(PillowTestCase):
self.assertEqual(out.size, croppedSize) self.assertEqual(out.size, croppedSize)
def test_copy_zero(self): def test_copy_zero(self):
im = Image.new('RGB', (0, 0)) im = Image.new("RGB", (0, 0))
out = im.copy() out = im.copy()
self.assertEqual(out.mode, im.mode) self.assertEqual(out.mode, im.mode)
self.assertEqual(out.size, im.size) self.assertEqual(out.size, im.size)

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImageCrop(PillowTestCase): class TestImageCrop(PillowTestCase):
def test_crop(self): def test_crop(self):
def crop(mode): def crop(mode):
im = hopper(mode) im = hopper(mode)
@ -13,11 +12,11 @@ class TestImageCrop(PillowTestCase):
cropped = im.crop((50, 50, 100, 100)) cropped = im.crop((50, 50, 100, 100))
self.assertEqual(cropped.mode, mode) self.assertEqual(cropped.mode, mode)
self.assertEqual(cropped.size, (50, 50)) self.assertEqual(cropped.size, (50, 50))
for mode in "1", "P", "L", "RGB", "I", "F": for mode in "1", "P", "L", "RGB", "I", "F":
crop(mode) crop(mode)
def test_wide_crop(self): def test_wide_crop(self):
def crop(*bbox): def crop(*bbox):
i = im.crop(bbox) i = im.crop(bbox)
h = i.histogram() h = i.histogram()
@ -74,7 +73,7 @@ class TestImageCrop(PillowTestCase):
# apparently a use after free on windows, see # apparently a use after free on windows, see
# https://github.com/python-pillow/Pillow/issues/1077 # https://github.com/python-pillow/Pillow/issues/1077
test_img = 'Tests/images/bmp/g/pal8-0.bmp' test_img = "Tests/images/bmp/g/pal8-0.bmp"
extents = (1, 1, 10, 10) extents = (1, 1, 10, 10)
# works prepatch # works prepatch
img = Image.open(test_img) img = Image.open(test_img)
@ -88,7 +87,7 @@ class TestImageCrop(PillowTestCase):
def test_crop_zero(self): def test_crop_zero(self):
im = Image.new('RGB', (0, 0), 'white') im = Image.new("RGB", (0, 0), "white")
cropped = im.crop((0, 0, 0, 0)) cropped = im.crop((0, 0, 0, 0))
self.assertEqual(cropped.size, (0, 0)) self.assertEqual(cropped.size, (0, 0))
@ -97,7 +96,7 @@ class TestImageCrop(PillowTestCase):
self.assertEqual(cropped.size, (10, 10)) self.assertEqual(cropped.size, (10, 10))
self.assertEqual(cropped.getdata()[0], (0, 0, 0)) self.assertEqual(cropped.getdata()[0], (0, 0, 0))
im = Image.new('RGB', (0, 0)) im = Image.new("RGB", (0, 0))
cropped = im.crop((10, 10, 20, 20)) cropped = im.crop((10, 10, 20, 20))
self.assertEqual(cropped.size, (10, 10)) self.assertEqual(cropped.size, (10, 10))

View File

@ -11,7 +11,7 @@ class TestImageDraft(PillowTestCase):
def draft_roundtrip(self, in_mode, in_size, req_mode, req_size): def draft_roundtrip(self, in_mode, in_size, req_mode, req_size):
im = Image.new(in_mode, in_size) im = Image.new(in_mode, in_size)
data = tostring(im, 'JPEG') data = tostring(im, "JPEG")
im = fromstring(data) im = fromstring(data)
im.draft(req_mode, req_size) im.draft(req_mode, req_size)
return im return im
@ -23,7 +23,6 @@ class TestImageDraft(PillowTestCase):
((128, 128), (64, 64), (64, 64)), ((128, 128), (64, 64), (64, 64)),
((128, 128), (32, 32), (32, 32)), ((128, 128), (32, 32), (32, 32)),
((128, 128), (16, 16), (16, 16)), ((128, 128), (16, 16), (16, 16)),
# large requested width # large requested width
((435, 361), (218, 128), (435, 361)), # almost 2x ((435, 361), (218, 128), (435, 361)), # almost 2x
((435, 361), (217, 128), (218, 181)), # more than 2x ((435, 361), (217, 128), (218, 181)), # more than 2x
@ -32,7 +31,6 @@ class TestImageDraft(PillowTestCase):
((435, 361), (55, 32), (109, 91)), # almost 8x ((435, 361), (55, 32), (109, 91)), # almost 8x
((435, 361), (54, 32), (55, 46)), # more than 8x ((435, 361), (54, 32), (55, 46)), # more than 8x
((435, 361), (27, 16), (55, 46)), # more than 16x ((435, 361), (27, 16), (55, 46)), # more than 16x
# and vice versa # and vice versa
((435, 361), (128, 181), (435, 361)), # almost 2x ((435, 361), (128, 181), (435, 361)), # almost 2x
((435, 361), (128, 180), (218, 181)), # more than 2x ((435, 361), (128, 180), (218, 181)), # more than 2x
@ -42,7 +40,7 @@ class TestImageDraft(PillowTestCase):
((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 = self.draft_roundtrip('L', in_size, None, req_size) im = self.draft_roundtrip("L", in_size, None, req_size)
im.load() im.load()
self.assertEqual(im.size, out_size) self.assertEqual(im.size, out_size)
@ -66,6 +64,6 @@ class TestImageDraft(PillowTestCase):
self.assertEqual(im.mode, out_mode) self.assertEqual(im.mode, out_mode)
def test_several_drafts(self): def test_several_drafts(self):
im = self.draft_roundtrip('L', (128, 128), None, (64, 64)) im = self.draft_roundtrip("L", (128, 128), None, (64, 64))
im.draft(None, (64, 64)) im.draft(None, (64, 64))
im.load() im.load()

View File

@ -4,9 +4,7 @@ from PIL import Image, ImageFilter
class TestImageFilter(PillowTestCase): class TestImageFilter(PillowTestCase):
def test_sanity(self): def test_sanity(self):
def filter(filter): def filter(filter):
for mode in ["L", "RGB", "CMYK"]: for mode in ["L", "RGB", "CMYK"]:
im = hopper(mode) im = hopper(mode)
@ -49,7 +47,6 @@ class TestImageFilter(PillowTestCase):
im.filter(ImageFilter.SMOOTH) im.filter(ImageFilter.SMOOTH)
def test_modefilter(self): def test_modefilter(self):
def modefilter(mode): def modefilter(mode):
im = Image.new(mode, (3, 3), None) im = Image.new(mode, (3, 3), None)
im.putdata(list(range(9))) im.putdata(list(range(9)))
@ -68,7 +65,6 @@ class TestImageFilter(PillowTestCase):
self.assertEqual(modefilter("RGB"), ((4, 0, 0), (0, 0, 0))) self.assertEqual(modefilter("RGB"), ((4, 0, 0), (0, 0, 0)))
def test_rankfilter(self): def test_rankfilter(self):
def rankfilter(mode): def rankfilter(mode):
im = Image.new(mode, (3, 3), None) im = Image.new(mode, (3, 3), None)
im.putdata(list(range(9))) im.putdata(list(range(9)))
@ -100,39 +96,48 @@ class TestImageFilter(PillowTestCase):
self.assertRaises(ValueError, builtinFilter.filter, hopper("P")) self.assertRaises(ValueError, builtinFilter.filter, hopper("P"))
def test_kernel_not_enough_coefficients(self): def test_kernel_not_enough_coefficients(self):
self.assertRaises(ValueError, self.assertRaises(ValueError, lambda: ImageFilter.Kernel((3, 3), (0, 0)))
lambda: ImageFilter.Kernel((3, 3), (0, 0)))
def test_consistency_3x3(self): def test_consistency_3x3(self):
source = Image.open("Tests/images/hopper.bmp") source = Image.open("Tests/images/hopper.bmp")
reference = Image.open("Tests/images/hopper_emboss.bmp") reference = Image.open("Tests/images/hopper_emboss.bmp")
kernel = ImageFilter.Kernel((3, 3), # noqa: E127 kernel = ImageFilter.Kernel( # noqa: E127
(-1, -1, 0, (3, 3),
-1, 0, 1, # fmt: off
0, 1, 1), .3) (-1, -1, 0,
-1, 0, 1,
0, 1, 1),
# fmt: on
0.3,
)
source = source.split() * 2 source = source.split() * 2
reference = reference.split() * 2 reference = reference.split() * 2
for mode in ['L', 'LA', 'RGB', 'CMYK']: for mode in ["L", "LA", "RGB", "CMYK"]:
self.assert_image_equal( self.assert_image_equal(
Image.merge(mode, source[:len(mode)]).filter(kernel), Image.merge(mode, source[: len(mode)]).filter(kernel),
Image.merge(mode, reference[:len(mode)]), Image.merge(mode, reference[: len(mode)]),
) )
def test_consistency_5x5(self): def test_consistency_5x5(self):
source = Image.open("Tests/images/hopper.bmp") source = Image.open("Tests/images/hopper.bmp")
reference = Image.open("Tests/images/hopper_emboss_more.bmp") reference = Image.open("Tests/images/hopper_emboss_more.bmp")
kernel = ImageFilter.Kernel((5, 5), # noqa: E127 kernel = ImageFilter.Kernel( # noqa: E127
(-1, -1, -1, -1, 0, (5, 5),
-1, -1, -1, 0, 1, # fmt: off
-1, -1, 0, 1, 1, (-1, -1, -1, -1, 0,
-1, 0, 1, 1, 1, -1, -1, -1, 0, 1,
0, 1, 1, 1, 1), 0.3) -1, -1, 0, 1, 1,
-1, 0, 1, 1, 1,
0, 1, 1, 1, 1),
# fmt: on
0.3,
)
source = source.split() * 2 source = source.split() * 2
reference = reference.split() * 2 reference = reference.split() * 2
for mode in ['L', 'LA', 'RGB', 'CMYK']: for mode in ["L", "LA", "RGB", "CMYK"]:
self.assert_image_equal( self.assert_image_equal(
Image.merge(mode, source[:len(mode)]).filter(kernel), Image.merge(mode, source[: len(mode)]).filter(kernel),
Image.merge(mode, reference[:len(mode)]), Image.merge(mode, reference[: len(mode)]),
) )

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImageFromBytes(PillowTestCase): class TestImageFromBytes(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im1 = hopper() im1 = hopper()
im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes()) im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes())

View File

@ -8,8 +8,8 @@ class TestFromQImage(PillowQtTestCase, PillowTestCase):
files_to_test = [ files_to_test = [
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"),
] ]
def roundtrip(self, expected): def roundtrip(self, expected):
@ -19,26 +19,26 @@ class TestFromQImage(PillowQtTestCase, PillowTestCase):
result = ImageQt.fromqimage(intermediate) result = ImageQt.fromqimage(intermediate)
if intermediate.hasAlphaChannel(): if intermediate.hasAlphaChannel():
self.assert_image_equal(result, expected.convert('RGBA')) self.assert_image_equal(result, expected.convert("RGBA"))
else: else:
self.assert_image_equal(result, expected.convert('RGB')) self.assert_image_equal(result, expected.convert("RGB"))
def test_sanity_1(self): def test_sanity_1(self):
for im in self.files_to_test: for im in self.files_to_test:
self.roundtrip(im.convert('1')) self.roundtrip(im.convert("1"))
def test_sanity_rgb(self): def test_sanity_rgb(self):
for im in self.files_to_test: for im in self.files_to_test:
self.roundtrip(im.convert('RGB')) self.roundtrip(im.convert("RGB"))
def test_sanity_rgba(self): def test_sanity_rgba(self):
for im in self.files_to_test: for im in self.files_to_test:
self.roundtrip(im.convert('RGBA')) self.roundtrip(im.convert("RGBA"))
def test_sanity_l(self): def test_sanity_l(self):
for im in self.files_to_test: for im in self.files_to_test:
self.roundtrip(im.convert('L')) self.roundtrip(im.convert("L"))
def test_sanity_p(self): def test_sanity_p(self):
for im in self.files_to_test: for im in self.files_to_test:
self.roundtrip(im.convert('P')) self.roundtrip(im.convert("P"))

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImageGetBands(PillowTestCase): class TestImageGetBands(PillowTestCase):
def test_getbands(self): def test_getbands(self):
self.assertEqual(Image.new("1", (1, 1)).getbands(), ("1",)) self.assertEqual(Image.new("1", (1, 1)).getbands(), ("1",))
self.assertEqual(Image.new("L", (1, 1)).getbands(), ("L",)) self.assertEqual(Image.new("L", (1, 1)).getbands(), ("L",))
@ -12,9 +11,6 @@ class TestImageGetBands(PillowTestCase):
self.assertEqual(Image.new("F", (1, 1)).getbands(), ("F",)) self.assertEqual(Image.new("F", (1, 1)).getbands(), ("F",))
self.assertEqual(Image.new("P", (1, 1)).getbands(), ("P",)) self.assertEqual(Image.new("P", (1, 1)).getbands(), ("P",))
self.assertEqual(Image.new("RGB", (1, 1)).getbands(), ("R", "G", "B")) self.assertEqual(Image.new("RGB", (1, 1)).getbands(), ("R", "G", "B"))
self.assertEqual( self.assertEqual(Image.new("RGBA", (1, 1)).getbands(), ("R", "G", "B", "A"))
Image.new("RGBA", (1, 1)).getbands(), ("R", "G", "B", "A")) self.assertEqual(Image.new("CMYK", (1, 1)).getbands(), ("C", "M", "Y", "K"))
self.assertEqual( self.assertEqual(Image.new("YCbCr", (1, 1)).getbands(), ("Y", "Cb", "Cr"))
Image.new("CMYK", (1, 1)).getbands(), ("C", "M", "Y", "K"))
self.assertEqual(
Image.new("YCbCr", (1, 1)).getbands(), ("Y", "Cb", "Cr"))

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImageGetBbox(PillowTestCase): class TestImageGetBbox(PillowTestCase):
def test_sanity(self): def test_sanity(self):
bbox = hopper().getbbox() bbox = hopper().getbbox()

View File

@ -2,9 +2,7 @@ from .helper import PillowTestCase, hopper
class TestImageGetColors(PillowTestCase): class TestImageGetColors(PillowTestCase):
def test_getcolors(self): def test_getcolors(self):
def getcolors(mode, limit=None): def getcolors(mode, limit=None):
im = hopper(mode) im = hopper(mode)
if limit: if limit:
@ -43,9 +41,11 @@ class TestImageGetColors(PillowTestCase):
im = hopper().quantize(3).convert("RGB") im = hopper().quantize(3).convert("RGB")
expected = [(4039, (172, 166, 181)), expected = [
(4385, (124, 113, 134)), (4039, (172, 166, 181)),
(7960, (31, 20, 33))] (4385, (124, 113, 134)),
(7960, (31, 20, 33)),
]
A = im.getcolors(maxcolors=2) A = im.getcolors(maxcolors=2)
self.assertIsNone(A) self.assertIsNone(A)

View File

@ -2,7 +2,6 @@ from .helper import PillowTestCase, hopper
class TestImageGetData(PillowTestCase): class TestImageGetData(PillowTestCase):
def test_sanity(self): def test_sanity(self):
data = hopper().getdata() data = hopper().getdata()
@ -13,7 +12,6 @@ class TestImageGetData(PillowTestCase):
self.assertEqual(data[0], (20, 20, 70)) self.assertEqual(data[0], (20, 20, 70))
def test_roundtrip(self): def test_roundtrip(self):
def getdata(mode): def getdata(mode):
im = hopper(mode).resize((32, 30)) im = hopper(mode).resize((32, 30))
data = im.getdata() data = im.getdata()

View File

@ -3,9 +3,7 @@ from .helper import PillowTestCase, hopper
class TestImageGetExtrema(PillowTestCase): class TestImageGetExtrema(PillowTestCase):
def test_extrema(self): def test_extrema(self):
def extrema(mode): def extrema(mode):
return hopper(mode).getextrema() return hopper(mode).getextrema()
@ -14,16 +12,13 @@ class TestImageGetExtrema(PillowTestCase):
self.assertEqual(extrema("I"), (0, 255)) self.assertEqual(extrema("I"), (0, 255))
self.assertEqual(extrema("F"), (0, 255)) self.assertEqual(extrema("F"), (0, 255))
self.assertEqual(extrema("P"), (0, 225)) # fixed palette self.assertEqual(extrema("P"), (0, 225)) # fixed palette
self.assertEqual( self.assertEqual(extrema("RGB"), ((0, 255), (0, 255), (0, 255)))
extrema("RGB"), ((0, 255), (0, 255), (0, 255))) self.assertEqual(extrema("RGBA"), ((0, 255), (0, 255), (0, 255), (255, 255)))
self.assertEqual( self.assertEqual(extrema("CMYK"), ((0, 255), (0, 255), (0, 255), (0, 0)))
extrema("RGBA"), ((0, 255), (0, 255), (0, 255), (255, 255)))
self.assertEqual(
extrema("CMYK"), ((0, 255), (0, 255), (0, 255), (0, 0)))
self.assertEqual(extrema("I;16"), (0, 255)) self.assertEqual(extrema("I;16"), (0, 255))
def test_true_16(self): def test_true_16(self):
im = Image.open("Tests/images/16_bit_noise.tif") im = Image.open("Tests/images/16_bit_noise.tif")
self.assertEqual(im.mode, 'I;16') self.assertEqual(im.mode, "I;16")
extrema = im.getextrema() extrema = im.getextrema()
self.assertEqual(extrema, (106, 285)) self.assertEqual(extrema, (106, 285))

View File

@ -3,7 +3,6 @@ from PIL._util import py3
class TestImageGetIm(PillowTestCase): class TestImageGetIm(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()
type_repr = repr(type(im.getim())) type_repr = repr(type(im.getim()))

View File

@ -2,13 +2,13 @@ from .helper import PillowTestCase, hopper
class TestImageGetPalette(PillowTestCase): class TestImageGetPalette(PillowTestCase):
def test_palette(self): def test_palette(self):
def palette(mode): def palette(mode):
p = hopper(mode).getpalette() p = hopper(mode).getpalette()
if p: if p:
return p[:10] return p[:10]
return None return None
self.assertIsNone(palette("1")) self.assertIsNone(palette("1"))
self.assertIsNone(palette("L")) self.assertIsNone(palette("L"))
self.assertIsNone(palette("I")) self.assertIsNone(palette("I"))

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImageGetProjection(PillowTestCase): class TestImageGetProjection(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()

View File

@ -2,9 +2,7 @@ from .helper import PillowTestCase, hopper
class TestImageHistogram(PillowTestCase): class TestImageHistogram(PillowTestCase):
def test_histogram(self): def test_histogram(self):
def histogram(mode): def histogram(mode):
h = hopper(mode).histogram() h = hopper(mode).histogram()
return len(h), min(h), max(h) return len(h), min(h), max(h)

View File

@ -6,7 +6,6 @@ import os
class TestImageLoad(PillowTestCase): class TestImageLoad(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImageMode(PillowTestCase): class TestImageMode(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()
@ -36,10 +35,13 @@ class TestImageMode(PillowTestCase):
def test_properties(self): def test_properties(self):
def check(mode, *result): def check(mode, *result):
signature = ( signature = (
Image.getmodebase(mode), Image.getmodetype(mode), Image.getmodebase(mode),
Image.getmodebands(mode), Image.getmodebandnames(mode), Image.getmodetype(mode),
) Image.getmodebands(mode),
Image.getmodebandnames(mode),
)
self.assertEqual(signature, result) self.assertEqual(signature, result)
check("1", "L", "L", 1, ("1",)) check("1", "L", "L", 1, ("1",))
check("L", "L", "L", 1, ("L",)) check("L", "L", "L", 1, ("L",))
check("P", "P", "L", 1, ("P",)) check("P", "P", "L", 1, ("P",))

View File

@ -9,10 +9,7 @@ class TestImagingPaste(PillowTestCase):
def assert_9points_image(self, im, expected): def assert_9points_image(self, im, expected):
expected = [ expected = [
point[0] point[0] if im.mode == "L" else point[: len(im.mode)] for point in expected
if im.mode == 'L' else
point[:len(im.mode)]
for point in expected
] ]
px = im.load() px = im.load()
actual = [ actual = [
@ -39,7 +36,7 @@ class TestImagingPaste(PillowTestCase):
@cached_property @cached_property
def mask_1(self): def mask_1(self):
mask = Image.new('1', (self.size, self.size)) mask = Image.new("1", (self.size, self.size))
px = mask.load() px = mask.load()
for y in range(mask.height): for y in range(mask.height):
for x in range(mask.width): for x in range(mask.width):
@ -52,7 +49,7 @@ class TestImagingPaste(PillowTestCase):
@cached_property @cached_property
def gradient_L(self): def gradient_L(self):
gradient = Image.new('L', (self.size, self.size)) gradient = Image.new("L", (self.size, self.size))
px = gradient.load() px = gradient.load()
for y in range(gradient.height): for y in range(gradient.height):
for x in range(gradient.width): for x in range(gradient.width):
@ -61,34 +58,43 @@ class TestImagingPaste(PillowTestCase):
@cached_property @cached_property
def gradient_RGB(self): def gradient_RGB(self):
return Image.merge('RGB', [ return Image.merge(
self.gradient_L, "RGB",
self.gradient_L.transpose(Image.ROTATE_90), [
self.gradient_L.transpose(Image.ROTATE_180), self.gradient_L,
]) self.gradient_L.transpose(Image.ROTATE_90),
self.gradient_L.transpose(Image.ROTATE_180),
],
)
@cached_property @cached_property
def gradient_RGBA(self): def gradient_RGBA(self):
return Image.merge('RGBA', [ return Image.merge(
self.gradient_L, "RGBA",
self.gradient_L.transpose(Image.ROTATE_90), [
self.gradient_L.transpose(Image.ROTATE_180), self.gradient_L,
self.gradient_L.transpose(Image.ROTATE_270), self.gradient_L.transpose(Image.ROTATE_90),
]) self.gradient_L.transpose(Image.ROTATE_180),
self.gradient_L.transpose(Image.ROTATE_270),
],
)
@cached_property @cached_property
def gradient_RGBa(self): def gradient_RGBa(self):
return Image.merge('RGBa', [ return Image.merge(
self.gradient_L, "RGBa",
self.gradient_L.transpose(Image.ROTATE_90), [
self.gradient_L.transpose(Image.ROTATE_180), self.gradient_L,
self.gradient_L.transpose(Image.ROTATE_270), self.gradient_L.transpose(Image.ROTATE_90),
]) self.gradient_L.transpose(Image.ROTATE_180),
self.gradient_L.transpose(Image.ROTATE_270),
],
)
def test_image_solid(self): def test_image_solid(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = Image.new(mode, (200, 200), 'red') im = Image.new(mode, (200, 200), "red")
im2 = getattr(self, 'gradient_' + mode) im2 = getattr(self, "gradient_" + mode)
im.paste(im2, (12, 23)) im.paste(im2, (12, 23))
@ -96,79 +102,99 @@ class TestImagingPaste(PillowTestCase):
self.assert_image_equal(im, im2) self.assert_image_equal(im, im2)
def test_image_mask_1(self): def test_image_mask_1(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = Image.new(mode, (200, 200), 'white') im = Image.new(mode, (200, 200), "white")
im2 = getattr(self, 'gradient_' + mode) im2 = getattr(self, "gradient_" + mode)
self.assert_9points_paste(im, im2, self.mask_1, [ self.assert_9points_paste(
(255, 255, 255, 255), im,
(255, 255, 255, 255), im2,
(127, 254, 127, 0), self.mask_1,
(255, 255, 255, 255), [
(255, 255, 255, 255), (255, 255, 255, 255),
(191, 190, 63, 64), (255, 255, 255, 255),
(127, 0, 127, 254), (127, 254, 127, 0),
(191, 64, 63, 190), (255, 255, 255, 255),
(255, 255, 255, 255), (255, 255, 255, 255),
]) (191, 190, 63, 64),
(127, 0, 127, 254),
(191, 64, 63, 190),
(255, 255, 255, 255),
],
)
def test_image_mask_L(self): def test_image_mask_L(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = Image.new(mode, (200, 200), 'white') im = Image.new(mode, (200, 200), "white")
im2 = getattr(self, 'gradient_' + mode) im2 = getattr(self, "gradient_" + mode)
self.assert_9points_paste(im, im2, self.mask_L, [ self.assert_9points_paste(
(128, 191, 255, 191), im,
(208, 239, 239, 208), im2,
(255, 255, 255, 255), self.mask_L,
(112, 111, 206, 207), [
(192, 191, 191, 191), (128, 191, 255, 191),
(239, 239, 207, 207), (208, 239, 239, 208),
(128, 1, 128, 254), (255, 255, 255, 255),
(207, 113, 112, 207), (112, 111, 206, 207),
(255, 191, 128, 191), (192, 191, 191, 191),
]) (239, 239, 207, 207),
(128, 1, 128, 254),
(207, 113, 112, 207),
(255, 191, 128, 191),
],
)
def test_image_mask_RGBA(self): def test_image_mask_RGBA(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = Image.new(mode, (200, 200), 'white') im = Image.new(mode, (200, 200), "white")
im2 = getattr(self, 'gradient_' + mode) im2 = getattr(self, "gradient_" + mode)
self.assert_9points_paste(im, im2, self.gradient_RGBA, [ self.assert_9points_paste(
(128, 191, 255, 191), im,
(208, 239, 239, 208), im2,
(255, 255, 255, 255), self.gradient_RGBA,
(112, 111, 206, 207), [
(192, 191, 191, 191), (128, 191, 255, 191),
(239, 239, 207, 207), (208, 239, 239, 208),
(128, 1, 128, 254), (255, 255, 255, 255),
(207, 113, 112, 207), (112, 111, 206, 207),
(255, 191, 128, 191), (192, 191, 191, 191),
]) (239, 239, 207, 207),
(128, 1, 128, 254),
(207, 113, 112, 207),
(255, 191, 128, 191),
],
)
def test_image_mask_RGBa(self): def test_image_mask_RGBa(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = Image.new(mode, (200, 200), 'white') im = Image.new(mode, (200, 200), "white")
im2 = getattr(self, 'gradient_' + mode) im2 = getattr(self, "gradient_" + mode)
self.assert_9points_paste(im, im2, self.gradient_RGBa, [ self.assert_9points_paste(
(128, 255, 126, 255), im,
(0, 127, 126, 255), im2,
(126, 253, 126, 255), self.gradient_RGBa,
(128, 127, 254, 255), [
(0, 255, 254, 255), (128, 255, 126, 255),
(126, 125, 254, 255), (0, 127, 126, 255),
(128, 1, 128, 255), (126, 253, 126, 255),
(0, 129, 128, 255), (128, 127, 254, 255),
(126, 255, 128, 255), (0, 255, 254, 255),
]) (126, 125, 254, 255),
(128, 1, 128, 255),
(0, 129, 128, 255),
(126, 255, 128, 255),
],
)
def test_color_solid(self): def test_color_solid(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = Image.new(mode, (200, 200), 'black') im = Image.new(mode, (200, 200), "black")
rect = (12, 23, 128 + 12, 128 + 23) rect = (12, 23, 128 + 12, 128 + 23)
im.paste('white', rect) im.paste("white", rect)
hist = im.crop(rect).histogram() hist = im.crop(rect).histogram()
while hist: while hist:
@ -177,76 +203,96 @@ class TestImagingPaste(PillowTestCase):
self.assertEqual(sum(head[:255]), 0) self.assertEqual(sum(head[:255]), 0)
def test_color_mask_1(self): def test_color_mask_1(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
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)]
self.assert_9points_paste(im, color, self.mask_1, [ self.assert_9points_paste(
(50, 60, 70, 80), im,
(50, 60, 70, 80), color,
(10, 20, 30, 40), self.mask_1,
(50, 60, 70, 80), [
(50, 60, 70, 80), (50, 60, 70, 80),
(10, 20, 30, 40), (50, 60, 70, 80),
(10, 20, 30, 40), (10, 20, 30, 40),
(10, 20, 30, 40), (50, 60, 70, 80),
(50, 60, 70, 80), (50, 60, 70, 80),
]) (10, 20, 30, 40),
(10, 20, 30, 40),
(10, 20, 30, 40),
(50, 60, 70, 80),
],
)
def test_color_mask_L(self): def test_color_mask_L(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = getattr(self, 'gradient_' + mode).copy() im = getattr(self, "gradient_" + mode).copy()
color = 'white' color = "white"
self.assert_9points_paste(im, color, self.mask_L, [ self.assert_9points_paste(
(127, 191, 254, 191), im,
(111, 207, 206, 110), color,
(127, 254, 127, 0), self.mask_L,
(207, 207, 239, 239), [
(191, 191, 190, 191), (127, 191, 254, 191),
(207, 206, 111, 112), (111, 207, 206, 110),
(254, 254, 254, 255), (127, 254, 127, 0),
(239, 206, 206, 238), (207, 207, 239, 239),
(254, 191, 127, 191), (191, 191, 190, 191),
]) (207, 206, 111, 112),
(254, 254, 254, 255),
(239, 206, 206, 238),
(254, 191, 127, 191),
],
)
def test_color_mask_RGBA(self): def test_color_mask_RGBA(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = getattr(self, 'gradient_' + mode).copy() im = getattr(self, "gradient_" + mode).copy()
color = 'white' color = "white"
self.assert_9points_paste(im, color, self.gradient_RGBA, [ self.assert_9points_paste(
(127, 191, 254, 191), im,
(111, 207, 206, 110), color,
(127, 254, 127, 0), self.gradient_RGBA,
(207, 207, 239, 239), [
(191, 191, 190, 191), (127, 191, 254, 191),
(207, 206, 111, 112), (111, 207, 206, 110),
(254, 254, 254, 255), (127, 254, 127, 0),
(239, 206, 206, 238), (207, 207, 239, 239),
(254, 191, 127, 191), (191, 191, 190, 191),
]) (207, 206, 111, 112),
(254, 254, 254, 255),
(239, 206, 206, 238),
(254, 191, 127, 191),
],
)
def test_color_mask_RGBa(self): def test_color_mask_RGBa(self):
for mode in ('RGBA', 'RGB', 'L'): for mode in ("RGBA", "RGB", "L"):
im = getattr(self, 'gradient_' + mode).copy() im = getattr(self, "gradient_" + mode).copy()
color = 'white' color = "white"
self.assert_9points_paste(im, color, self.gradient_RGBa, [ self.assert_9points_paste(
(255, 63, 126, 63), im,
(47, 143, 142, 46), color,
(126, 253, 126, 255), self.gradient_RGBa,
(15, 15, 47, 47), [
(63, 63, 62, 63), (255, 63, 126, 63),
(142, 141, 46, 47), (47, 143, 142, 46),
(255, 255, 255, 0), (126, 253, 126, 255),
(48, 15, 15, 47), (15, 15, 47, 47),
(126, 63, 255, 63) (63, 63, 62, 63),
]) (142, 141, 46, 47),
(255, 255, 255, 0),
(48, 15, 15, 47),
(126, 63, 255, 63),
],
)
def test_different_sizes(self): def test_different_sizes(self):
im = Image.new('RGB', (100, 100)) im = Image.new("RGB", (100, 100))
im2 = Image.new('RGB', (50, 50)) im2 = Image.new("RGB", (50, 50))
im.copy().paste(im2) im.copy().paste(im2)
im.copy().paste(im2, (0, 0)) im.copy().paste(im2, (0, 0))

View File

@ -2,39 +2,38 @@ from .helper import PillowTestCase, hopper
class TestImagePoint(PillowTestCase): class TestImagePoint(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()
self.assertRaises(ValueError, im.point, list(range(256))) self.assertRaises(ValueError, im.point, list(range(256)))
im.point(list(range(256))*3) im.point(list(range(256)) * 3)
im.point(lambda x: x) im.point(lambda x: x)
im = im.convert("I") im = im.convert("I")
self.assertRaises(ValueError, im.point, list(range(256))) self.assertRaises(ValueError, im.point, list(range(256)))
im.point(lambda x: x*1) im.point(lambda x: x * 1)
im.point(lambda x: x+1) im.point(lambda x: x + 1)
im.point(lambda x: x*1+1) im.point(lambda x: x * 1 + 1)
self.assertRaises(TypeError, im.point, lambda x: x-1) self.assertRaises(TypeError, im.point, lambda x: x - 1)
self.assertRaises(TypeError, im.point, lambda x: x/1) self.assertRaises(TypeError, im.point, lambda x: x / 1)
def test_16bit_lut(self): def test_16bit_lut(self):
""" Tests for 16 bit -> 8 bit lut for converting I->L images """ Tests for 16 bit -> 8 bit lut for converting I->L images
see https://github.com/python-pillow/Pillow/issues/440 see https://github.com/python-pillow/Pillow/issues/440
""" """
im = hopper("I") im = hopper("I")
im.point(list(range(256))*256, 'L') im.point(list(range(256)) * 256, "L")
def test_f_lut(self): def test_f_lut(self):
""" Tests for floating point lut of 8bit gray image """ """ Tests for floating point lut of 8bit gray image """
im = hopper('L') im = hopper("L")
lut = [0.5 * float(x) for x in range(256)] lut = [0.5 * float(x) for x in range(256)]
out = im.point(lut, 'F') out = im.point(lut, "F")
int_lut = [x//2 for x in range(256)] int_lut = [x // 2 for x in range(256)]
self.assert_image_equal(out.convert('L'), im.point(int_lut, 'L')) self.assert_image_equal(out.convert("L"), im.point(int_lut, "L"))
def test_f_mode(self): def test_f_mode(self):
im = hopper('F') im = hopper("F")
self.assertRaises(ValueError, im.point, None) self.assertRaises(ValueError, im.point, None)

View File

@ -4,7 +4,6 @@ from PIL import Image
class TestImagePutAlpha(PillowTestCase): class TestImagePutAlpha(PillowTestCase):
def test_interface(self): def test_interface(self):
im = Image.new("RGBA", (1, 1), (1, 2, 3, 0)) im = Image.new("RGBA", (1, 1), (1, 2, 3, 0))
@ -25,21 +24,21 @@ class TestImagePutAlpha(PillowTestCase):
self.assertEqual(im.getpixel((0, 0)), 1) self.assertEqual(im.getpixel((0, 0)), 1)
im.putalpha(2) im.putalpha(2)
self.assertEqual(im.mode, 'LA') self.assertEqual(im.mode, "LA")
self.assertEqual(im.getpixel((0, 0)), (1, 2)) self.assertEqual(im.getpixel((0, 0)), (1, 2))
im = Image.new("P", (1, 1), 1) im = Image.new("P", (1, 1), 1)
self.assertEqual(im.getpixel((0, 0)), 1) self.assertEqual(im.getpixel((0, 0)), 1)
im.putalpha(2) im.putalpha(2)
self.assertEqual(im.mode, 'PA') self.assertEqual(im.mode, "PA")
self.assertEqual(im.getpixel((0, 0)), (1, 2)) self.assertEqual(im.getpixel((0, 0)), (1, 2))
im = Image.new("RGB", (1, 1), (1, 2, 3)) im = Image.new("RGB", (1, 1), (1, 2, 3))
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3)) self.assertEqual(im.getpixel((0, 0)), (1, 2, 3))
im.putalpha(4) im.putalpha(4)
self.assertEqual(im.mode, 'RGBA') self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4)) self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4))
def test_readonly(self): def test_readonly(self):
@ -49,5 +48,5 @@ class TestImagePutAlpha(PillowTestCase):
im.putalpha(4) im.putalpha(4)
self.assertFalse(im.readonly) self.assertFalse(im.readonly)
self.assertEqual(im.mode, 'RGBA') self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4)) self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4))

View File

@ -7,7 +7,6 @@ from PIL import Image
class TestImagePutData(PillowTestCase): class TestImagePutData(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im1 = hopper() im1 = hopper()
@ -33,32 +32,33 @@ class TestImagePutData(PillowTestCase):
im = Image.new("RGBA", (1, 1)) im = Image.new("RGBA", (1, 1))
im.putdata([value]) im.putdata([value])
return im.getpixel((0, 0)) return im.getpixel((0, 0))
self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255)) self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255))
self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255)) self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255))
self.assertEqual(put(-1), (255, 255, 255, 255)) self.assertEqual(put(-1), (255, 255, 255, 255))
self.assertEqual(put(-1), (255, 255, 255, 255)) self.assertEqual(put(-1), (255, 255, 255, 255))
if sys.maxsize > 2**32: if sys.maxsize > 2 ** 32:
self.assertEqual(put(sys.maxsize), (255, 255, 255, 255)) self.assertEqual(put(sys.maxsize), (255, 255, 255, 255))
else: else:
self.assertEqual(put(sys.maxsize), (255, 255, 255, 127)) self.assertEqual(put(sys.maxsize), (255, 255, 255, 127))
def test_pypy_performance(self): def test_pypy_performance(self):
im = Image.new('L', (256, 256)) im = Image.new("L", (256, 256))
im.putdata(list(range(256))*256) im.putdata(list(range(256)) * 256)
def test_mode_i(self): def test_mode_i(self):
src = hopper('L') src = hopper("L")
data = list(src.getdata()) data = list(src.getdata())
im = Image.new('I', src.size, 0) im = Image.new("I", src.size, 0)
im.putdata(data, 2, 256) im.putdata(data, 2, 256)
target = [2 * elt + 256 for elt in data] target = [2 * elt + 256 for elt in data]
self.assertEqual(list(im.getdata()), target) self.assertEqual(list(im.getdata()), target)
def test_mode_F(self): def test_mode_F(self):
src = hopper('L') src = hopper("L")
data = list(src.getdata()) data = list(src.getdata())
im = Image.new('F', src.size, 0) im = Image.new("F", src.size, 0)
im.putdata(data, 2.0, 256.0) im.putdata(data, 2.0, 256.0)
target = [2.0 * float(elt) + 256.0 for elt in data] target = [2.0 * float(elt) + 256.0 for elt in data]
@ -68,8 +68,8 @@ class TestImagePutData(PillowTestCase):
# shouldn't segfault # shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008 # see https://github.com/python-pillow/Pillow/issues/1008
arr = array('B', [0])*15000 arr = array("B", [0]) * 15000
im = Image.new('L', (150, 100)) im = Image.new("L", (150, 100))
im.putdata(arr) im.putdata(arr)
self.assertEqual(len(im.getdata()), len(arr)) self.assertEqual(len(im.getdata()), len(arr))
@ -78,8 +78,8 @@ class TestImagePutData(PillowTestCase):
# shouldn't segfault # shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008 # see https://github.com/python-pillow/Pillow/issues/1008
im = Image.new('F', (150, 100)) im = Image.new("F", (150, 100))
arr = array('f', [0.0])*15000 arr = array("f", [0.0]) * 15000
im.putdata(arr) im.putdata(arr)
self.assertEqual(len(im.getdata()), len(arr)) self.assertEqual(len(im.getdata()), len(arr))

View File

@ -4,20 +4,21 @@ from PIL import ImagePalette
class TestImagePutPalette(PillowTestCase): class TestImagePutPalette(PillowTestCase):
def test_putpalette(self): def test_putpalette(self):
def palette(mode): def palette(mode):
im = hopper(mode).copy() im = hopper(mode).copy()
im.putpalette(list(range(256))*3) im.putpalette(list(range(256)) * 3)
p = im.getpalette() p = im.getpalette()
if p: if p:
return im.mode, p[:10] return im.mode, p[:10]
return im.mode return im.mode
self.assertRaises(ValueError, palette, "1") self.assertRaises(ValueError, palette, "1")
for mode in ["L", "LA", "P", "PA"]: for mode in ["L", "LA", "P", "PA"]:
self.assertEqual(palette(mode), self.assertEqual(
("PA" if "A" in mode else "P", palette(mode),
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) ("PA" if "A" in mode else "P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
)
self.assertRaises(ValueError, palette, "I") self.assertRaises(ValueError, palette, "I")
self.assertRaises(ValueError, palette, "F") self.assertRaises(ValueError, palette, "F")
self.assertRaises(ValueError, palette, "RGB") self.assertRaises(ValueError, palette, "RGB")

View File

@ -4,60 +4,59 @@ from PIL import Image
class TestImageQuantize(PillowTestCase): class TestImageQuantize(PillowTestCase):
def test_sanity(self): def test_sanity(self):
image = hopper() image = hopper()
converted = image.quantize() converted = image.quantize()
self.assert_image(converted, 'P', converted.size) self.assert_image(converted, "P", converted.size)
self.assert_image_similar(converted.convert('RGB'), image, 10) self.assert_image_similar(converted.convert("RGB"), image, 10)
image = hopper() image = hopper()
converted = image.quantize(palette=hopper('P')) converted = image.quantize(palette=hopper("P"))
self.assert_image(converted, 'P', converted.size) self.assert_image(converted, "P", converted.size)
self.assert_image_similar(converted.convert('RGB'), image, 60) self.assert_image_similar(converted.convert("RGB"), image, 60)
def test_libimagequant_quantize(self): def test_libimagequant_quantize(self):
image = hopper() image = hopper()
try: try:
converted = image.quantize(100, Image.LIBIMAGEQUANT) converted = image.quantize(100, Image.LIBIMAGEQUANT)
except ValueError as ex: except ValueError as ex:
if 'dependency' in str(ex).lower(): if "dependency" in str(ex).lower():
self.skipTest('libimagequant support not available') self.skipTest("libimagequant support not available")
else: else:
raise raise
self.assert_image(converted, 'P', converted.size) self.assert_image(converted, "P", converted.size)
self.assert_image_similar(converted.convert('RGB'), image, 15) self.assert_image_similar(converted.convert("RGB"), image, 15)
self.assertEqual(len(converted.getcolors()), 100) self.assertEqual(len(converted.getcolors()), 100)
def test_octree_quantize(self): def test_octree_quantize(self):
image = hopper() image = hopper()
converted = image.quantize(100, Image.FASTOCTREE) converted = image.quantize(100, Image.FASTOCTREE)
self.assert_image(converted, 'P', converted.size) self.assert_image(converted, "P", converted.size)
self.assert_image_similar(converted.convert('RGB'), image, 20) self.assert_image_similar(converted.convert("RGB"), image, 20)
self.assertEqual(len(converted.getcolors()), 100) self.assertEqual(len(converted.getcolors()), 100)
def test_rgba_quantize(self): def test_rgba_quantize(self):
image = hopper('RGBA') image = hopper("RGBA")
self.assertRaises(ValueError, image.quantize, method=0) self.assertRaises(ValueError, image.quantize, method=0)
self.assertEqual(image.quantize().convert().mode, "RGBA") self.assertEqual(image.quantize().convert().mode, "RGBA")
def test_quantize(self): def test_quantize(self):
image = Image.open('Tests/images/caption_6_33_22.png').convert('RGB') image = Image.open("Tests/images/caption_6_33_22.png").convert("RGB")
converted = image.quantize() converted = image.quantize()
self.assert_image(converted, 'P', converted.size) self.assert_image(converted, "P", converted.size)
self.assert_image_similar(converted.convert('RGB'), image, 1) self.assert_image_similar(converted.convert("RGB"), image, 1)
def test_quantize_no_dither(self): def test_quantize_no_dither(self):
image = hopper() image = hopper()
palette = Image.open('Tests/images/caption_6_33_22.png').convert('P') palette = Image.open("Tests/images/caption_6_33_22.png").convert("P")
converted = image.quantize(dither=0, palette=palette) converted = image.quantize(dither=0, palette=palette)
self.assert_image(converted, 'P', converted.size) self.assert_image(converted, "P", converted.size)
def test_quantize_dither_diff(self): def test_quantize_dither_diff(self):
image = hopper() image = hopper()
palette = Image.open('Tests/images/caption_6_33_22.png').convert('P') palette = Image.open("Tests/images/caption_6_33_22.png").convert("P")
dither = image.quantize(dither=1, palette=palette) dither = image.quantize(dither=1, palette=palette)
nodither = image.quantize(dither=0, palette=palette) nodither = image.quantize(dither=0, palette=palette)

View File

@ -9,7 +9,7 @@ from PIL import Image, ImageDraw
class TestImagingResampleVulnerability(PillowTestCase): class TestImagingResampleVulnerability(PillowTestCase):
# see https://github.com/python-pillow/Pillow/issues/1710 # see https://github.com/python-pillow/Pillow/issues/1710
def test_overflow(self): def test_overflow(self):
im = hopper('L') im = hopper("L")
xsize = 0x100000008 // 4 xsize = 0x100000008 // 4
ysize = 1000 # unimportant ysize = 1000 # unimportant
with self.assertRaises(MemoryError): with self.assertRaises(MemoryError):
@ -29,11 +29,11 @@ class TestImagingResampleVulnerability(PillowTestCase):
im.resize((100, -100)) im.resize((100, -100))
def test_modify_after_resizing(self): def test_modify_after_resizing(self):
im = hopper('RGB') im = hopper("RGB")
# get copy with same size # get copy with same size
copy = im.resize(im.size) copy = im.resize(im.size)
# some in-place operation # some in-place operation
copy.paste('black', (0, 0, im.width // 2, im.height // 2)) copy.paste("black", (0, 0, im.width // 2, im.height // 2))
# image should be different # image should be different
self.assertNotEqual(im.tobytes(), copy.tobytes()) self.assertNotEqual(im.tobytes(), copy.tobytes())
@ -47,7 +47,7 @@ class TestImagingCoreResampleAccuracy(PillowTestCase):
1f 1f e0 e0 1f 1f e0 e0
1f 1f e0 e0 1f 1f e0 e0
""" """
case = Image.new('L', size, 255 - color) case = Image.new("L", size, 255 - color)
rectangle = ImageDraw.Draw(case).rectangle rectangle = ImageDraw.Draw(case).rectangle
rectangle((0, 0, size[0] // 2 - 1, size[1] // 2 - 1), color) rectangle((0, 0, size[0] // 2 - 1, size[1] // 2 - 1), color)
rectangle((size[0] // 2, size[1] // 2, size[0], size[1]), color) rectangle((size[0] // 2, size[1] // 2, size[0], size[1]), color)
@ -58,13 +58,13 @@ class TestImagingCoreResampleAccuracy(PillowTestCase):
"""Restores a sample image from given data string which contains """Restores a sample image from given data string which contains
hex-encoded pixels from the top left fourth of a sample. hex-encoded pixels from the top left fourth of a sample.
""" """
data = data.replace(' ', '') data = data.replace(" ", "")
sample = Image.new('L', size) sample = Image.new("L", size)
s_px = sample.load() s_px = sample.load()
w, h = size[0] // 2, size[1] // 2 w, h = size[0] // 2, size[1] // 2
for y in range(h): for y in range(h):
for x in range(w): for x in range(w):
val = int(data[(y * w + x) * 2:(y * w + x + 1) * 2], 16) val = int(data[(y * w + x) * 2 : (y * w + x + 1) * 2], 16)
s_px[x, y] = val s_px[x, y] = val
s_px[size[0] - x - 1, size[1] - y - 1] = val s_px[size[0] - x - 1, size[1] - y - 1] = val
s_px[x, size[1] - y - 1] = 255 - val s_px[x, size[1] - y - 1] = 255 - val
@ -77,118 +77,134 @@ class TestImagingCoreResampleAccuracy(PillowTestCase):
for y in range(case.size[1]): for y in range(case.size[1]):
for x in range(case.size[0]): for x in range(case.size[0]):
if c_px[x, y] != s_px[x, y]: if c_px[x, y] != s_px[x, y]:
message = '\nHave: \n{}\n\nExpected: \n{}'.format( message = "\nHave: \n{}\n\nExpected: \n{}".format(
self.serialize_image(case), self.serialize_image(case), self.serialize_image(sample)
self.serialize_image(sample),
) )
self.assertEqual(s_px[x, y], c_px[x, y], message) self.assertEqual(s_px[x, y], c_px[x, y], message)
def serialize_image(self, image): def serialize_image(self, image):
s_px = image.load() s_px = image.load()
return '\n'.join( return "\n".join(
' '.join( " ".join("{:02x}".format(s_px[x, y]) for x in range(image.size[0]))
'{:02x}'.format(s_px[x, y])
for x in range(image.size[0])
)
for y in range(image.size[1]) for y in range(image.size[1])
) )
def test_reduce_box(self): def test_reduce_box(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (8, 8), 0xe1) case = self.make_case(mode, (8, 8), 0xE1)
case = case.resize((4, 4), Image.BOX) case = case.resize((4, 4), Image.BOX)
data = ('e1 e1' # fmt: off
'e1 e1') data = ("e1 e1"
"e1 e1")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (4, 4))) self.check_case(channel, self.make_sample(data, (4, 4)))
def test_reduce_bilinear(self): def test_reduce_bilinear(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (8, 8), 0xe1) case = self.make_case(mode, (8, 8), 0xE1)
case = case.resize((4, 4), Image.BILINEAR) case = case.resize((4, 4), Image.BILINEAR)
data = ('e1 c9' # fmt: off
'c9 b7') data = ("e1 c9"
"c9 b7")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (4, 4))) self.check_case(channel, self.make_sample(data, (4, 4)))
def test_reduce_hamming(self): def test_reduce_hamming(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (8, 8), 0xe1) case = self.make_case(mode, (8, 8), 0xE1)
case = case.resize((4, 4), Image.HAMMING) case = case.resize((4, 4), Image.HAMMING)
data = ('e1 da' # fmt: off
'da d3') data = ("e1 da"
"da d3")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (4, 4))) self.check_case(channel, self.make_sample(data, (4, 4)))
def test_reduce_bicubic(self): def test_reduce_bicubic(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (12, 12), 0xe1) case = self.make_case(mode, (12, 12), 0xE1)
case = case.resize((6, 6), Image.BICUBIC) case = case.resize((6, 6), Image.BICUBIC)
data = ('e1 e3 d4' # fmt: off
'e3 e5 d6' data = ("e1 e3 d4"
'd4 d6 c9') "e3 e5 d6"
"d4 d6 c9")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (6, 6))) self.check_case(channel, self.make_sample(data, (6, 6)))
def test_reduce_lanczos(self): def test_reduce_lanczos(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (16, 16), 0xe1) case = self.make_case(mode, (16, 16), 0xE1)
case = case.resize((8, 8), Image.LANCZOS) case = case.resize((8, 8), Image.LANCZOS)
data = ('e1 e0 e4 d7' # fmt: off
'e0 df e3 d6' data = ("e1 e0 e4 d7"
'e4 e3 e7 da' "e0 df e3 d6"
'd7 d6 d9 ce') "e4 e3 e7 da"
"d7 d6 d9 ce")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (8, 8))) self.check_case(channel, self.make_sample(data, (8, 8)))
def test_enlarge_box(self): def test_enlarge_box(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (2, 2), 0xe1) case = self.make_case(mode, (2, 2), 0xE1)
case = case.resize((4, 4), Image.BOX) case = case.resize((4, 4), Image.BOX)
data = ('e1 e1' # fmt: off
'e1 e1') data = ("e1 e1"
"e1 e1")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (4, 4))) self.check_case(channel, self.make_sample(data, (4, 4)))
def test_enlarge_bilinear(self): def test_enlarge_bilinear(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (2, 2), 0xe1) case = self.make_case(mode, (2, 2), 0xE1)
case = case.resize((4, 4), Image.BILINEAR) case = case.resize((4, 4), Image.BILINEAR)
data = ('e1 b0' # fmt: off
'b0 98') data = ("e1 b0"
"b0 98")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (4, 4))) self.check_case(channel, self.make_sample(data, (4, 4)))
def test_enlarge_hamming(self): def test_enlarge_hamming(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (2, 2), 0xe1) case = self.make_case(mode, (2, 2), 0xE1)
case = case.resize((4, 4), Image.HAMMING) case = case.resize((4, 4), Image.HAMMING)
data = ('e1 d2' # fmt: off
'd2 c5') data = ("e1 d2"
"d2 c5")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (4, 4))) self.check_case(channel, self.make_sample(data, (4, 4)))
def test_enlarge_bicubic(self): def test_enlarge_bicubic(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (4, 4), 0xe1) case = self.make_case(mode, (4, 4), 0xE1)
case = case.resize((8, 8), Image.BICUBIC) case = case.resize((8, 8), Image.BICUBIC)
data = ('e1 e5 ee b9' # fmt: off
'e5 e9 f3 bc' data = ("e1 e5 ee b9"
'ee f3 fd c1' "e5 e9 f3 bc"
'b9 bc c1 a2') "ee f3 fd c1"
"b9 bc c1 a2")
# fmt: on
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (8, 8))) self.check_case(channel, self.make_sample(data, (8, 8)))
def test_enlarge_lanczos(self): def test_enlarge_lanczos(self):
for mode in ['RGBX', 'RGB', 'La', 'L']: for mode in ["RGBX", "RGB", "La", "L"]:
case = self.make_case(mode, (6, 6), 0xe1) case = self.make_case(mode, (6, 6), 0xE1)
case = case.resize((12, 12), Image.LANCZOS) case = case.resize((12, 12), Image.LANCZOS)
data = ('e1 e0 db ed f5 b8' data = (
'e0 df da ec f3 b7' "e1 e0 db ed f5 b8"
'db db d6 e7 ee b5' "e0 df da ec f3 b7"
'ed ec e6 fb ff bf' "db db d6 e7 ee b5"
'f5 f4 ee ff ff c4' "ed ec e6 fb ff bf"
'b8 b7 b4 bf c4 a0') "f5 f4 ee ff ff c4"
"b8 b7 b4 bf c4 a0"
)
for channel in case.split(): for channel in case.split():
self.check_case(channel, self.make_sample(data, (12, 12))) self.check_case(channel, self.make_sample(data, (12, 12)))
@ -204,29 +220,28 @@ class CoreResampleConsistencyTest(PillowTestCase):
for x in range(channel.size[0]): for x in range(channel.size[0]):
for y in range(channel.size[1]): for y in range(channel.size[1]):
if px[x, y] != color: if px[x, y] != color:
message = "{} != {} for pixel {}".format( message = "{} != {} for pixel {}".format(px[x, y], color, (x, y))
px[x, y], color, (x, y))
self.assertEqual(px[x, y], color, message) self.assertEqual(px[x, y], color, message)
def test_8u(self): def test_8u(self):
im, color = self.make_case('RGB', (0, 64, 255)) im, color = self.make_case("RGB", (0, 64, 255))
r, g, b = im.split() r, g, b = im.split()
self.run_case((r, color[0])) self.run_case((r, color[0]))
self.run_case((g, color[1])) self.run_case((g, color[1]))
self.run_case((b, color[2])) self.run_case((b, color[2]))
self.run_case(self.make_case('L', 12)) self.run_case(self.make_case("L", 12))
def test_32i(self): def test_32i(self):
self.run_case(self.make_case('I', 12)) self.run_case(self.make_case("I", 12))
self.run_case(self.make_case('I', 0x7fffffff)) self.run_case(self.make_case("I", 0x7FFFFFFF))
self.run_case(self.make_case('I', -12)) self.run_case(self.make_case("I", -12))
self.run_case(self.make_case('I', -1 << 31)) self.run_case(self.make_case("I", -1 << 31))
def test_32f(self): def test_32f(self):
self.run_case(self.make_case('F', 1)) self.run_case(self.make_case("F", 1))
self.run_case(self.make_case('F', 3.40282306074e+38)) self.run_case(self.make_case("F", 3.40282306074e38))
self.run_case(self.make_case('F', 1.175494e-38)) self.run_case(self.make_case("F", 1.175494e-38))
self.run_case(self.make_case('F', 1.192093e-07)) self.run_case(self.make_case("F", 1.192093e-07))
class CoreResampleAlphaCorrectTest(PillowTestCase): class CoreResampleAlphaCorrectTest(PillowTestCase):
@ -244,13 +259,16 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
px = i.load() px = i.load()
for y in range(i.size[1]): for y in range(i.size[1]):
used_colors = {px[x, y][0] for x in range(i.size[0])} used_colors = {px[x, y][0] for x in range(i.size[0])}
self.assertEqual(256, len(used_colors), self.assertEqual(
'All colors should present in resized image. ' 256,
'Only {} on {} line.'.format(len(used_colors), y)) len(used_colors),
"All colors should present in resized image. "
"Only {} on {} line.".format(len(used_colors), y),
)
@unittest.skip("current implementation isn't precise enough") @unittest.skip("current implementation isn't precise enough")
def test_levels_rgba(self): def test_levels_rgba(self):
case = self.make_levels_case('RGBA') case = self.make_levels_case("RGBA")
self.run_levels_case(case.resize((512, 32), Image.BOX)) self.run_levels_case(case.resize((512, 32), Image.BOX))
self.run_levels_case(case.resize((512, 32), Image.BILINEAR)) self.run_levels_case(case.resize((512, 32), Image.BILINEAR))
self.run_levels_case(case.resize((512, 32), Image.HAMMING)) self.run_levels_case(case.resize((512, 32), Image.HAMMING))
@ -259,7 +277,7 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
@unittest.skip("current implementation isn't precise enough") @unittest.skip("current implementation isn't precise enough")
def test_levels_la(self): def test_levels_la(self):
case = self.make_levels_case('LA') case = self.make_levels_case("LA")
self.run_levels_case(case.resize((512, 32), Image.BOX)) self.run_levels_case(case.resize((512, 32), Image.BOX))
self.run_levels_case(case.resize((512, 32), Image.BILINEAR)) self.run_levels_case(case.resize((512, 32), Image.BILINEAR))
self.run_levels_case(case.resize((512, 32), Image.HAMMING)) self.run_levels_case(case.resize((512, 32), Image.HAMMING))
@ -281,24 +299,21 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
for y in range(i.size[1]): for y in range(i.size[1]):
for x in range(i.size[0]): for x in range(i.size[0]):
if px[x, y][-1] != 0 and px[x, y][:-1] != clean_pixel: if px[x, y][-1] != 0 and px[x, y][:-1] != clean_pixel:
message = 'pixel at ({}, {}) is differ:\n{}\n{}'\ message = "pixel at ({}, {}) is differ:\n{}\n{}".format(
.format(x, y, px[x, y], clean_pixel) x, y, px[x, y], clean_pixel
)
self.assertEqual(px[x, y][:3], clean_pixel, message) self.assertEqual(px[x, y][:3], clean_pixel, message)
def test_dirty_pixels_rgba(self): def test_dirty_pixels_rgba(self):
case = self.make_dirty_case('RGBA', (255, 255, 0, 128), (0, 0, 255, 0)) case = self.make_dirty_case("RGBA", (255, 255, 0, 128), (0, 0, 255, 0))
self.run_dirty_case(case.resize((20, 20), Image.BOX), (255, 255, 0)) self.run_dirty_case(case.resize((20, 20), Image.BOX), (255, 255, 0))
self.run_dirty_case(case.resize((20, 20), Image.BILINEAR), self.run_dirty_case(case.resize((20, 20), Image.BILINEAR), (255, 255, 0))
(255, 255, 0)) self.run_dirty_case(case.resize((20, 20), Image.HAMMING), (255, 255, 0))
self.run_dirty_case(case.resize((20, 20), Image.HAMMING), self.run_dirty_case(case.resize((20, 20), Image.BICUBIC), (255, 255, 0))
(255, 255, 0)) self.run_dirty_case(case.resize((20, 20), Image.LANCZOS), (255, 255, 0))
self.run_dirty_case(case.resize((20, 20), Image.BICUBIC),
(255, 255, 0))
self.run_dirty_case(case.resize((20, 20), Image.LANCZOS),
(255, 255, 0))
def test_dirty_pixels_la(self): def test_dirty_pixels_la(self):
case = self.make_dirty_case('LA', (255, 128), (0, 0)) case = self.make_dirty_case("LA", (255, 128), (0, 0))
self.run_dirty_case(case.resize((20, 20), Image.BOX), (255,)) self.run_dirty_case(case.resize((20, 20), Image.BOX), (255,))
self.run_dirty_case(case.resize((20, 20), Image.BILINEAR), (255,)) self.run_dirty_case(case.resize((20, 20), Image.BILINEAR), (255,))
self.run_dirty_case(case.resize((20, 20), Image.HAMMING), (255,)) self.run_dirty_case(case.resize((20, 20), Image.HAMMING), (255,))
@ -309,27 +324,27 @@ class CoreResampleAlphaCorrectTest(PillowTestCase):
class CoreResamplePassesTest(PillowTestCase): class CoreResamplePassesTest(PillowTestCase):
@contextmanager @contextmanager
def count(self, diff): def count(self, diff):
count = Image.core.get_stats()['new_count'] count = Image.core.get_stats()["new_count"]
yield yield
self.assertEqual(Image.core.get_stats()['new_count'] - count, diff) self.assertEqual(Image.core.get_stats()["new_count"] - count, diff)
def test_horizontal(self): def test_horizontal(self):
im = hopper('L') im = hopper("L")
with self.count(1): with self.count(1):
im.resize((im.size[0] - 10, im.size[1]), Image.BILINEAR) im.resize((im.size[0] - 10, im.size[1]), Image.BILINEAR)
def test_vertical(self): def test_vertical(self):
im = hopper('L') im = hopper("L")
with self.count(1): with self.count(1):
im.resize((im.size[0], im.size[1] - 10), Image.BILINEAR) im.resize((im.size[0], im.size[1] - 10), Image.BILINEAR)
def test_both(self): def test_both(self):
im = hopper('L') im = hopper("L")
with self.count(2): with self.count(2):
im.resize((im.size[0] - 10, im.size[1] - 10), Image.BILINEAR) im.resize((im.size[0] - 10, im.size[1] - 10), Image.BILINEAR)
def test_box_horizontal(self): def test_box_horizontal(self):
im = hopper('L') im = hopper("L")
box = (20, 0, im.size[0] - 20, im.size[1]) box = (20, 0, im.size[0] - 20, im.size[1])
with self.count(1): with self.count(1):
# the same size, but different box # the same size, but different box
@ -339,7 +354,7 @@ class CoreResamplePassesTest(PillowTestCase):
self.assert_image_similar(with_box, cropped, 0.1) self.assert_image_similar(with_box, cropped, 0.1)
def test_box_vertical(self): def test_box_vertical(self):
im = hopper('L') im = hopper("L")
box = (0, 20, im.size[0], im.size[1] - 20) box = (0, 20, im.size[0], im.size[1] - 20)
with self.count(1): with self.count(1):
# the same size, but different box # the same size, but different box
@ -354,7 +369,7 @@ class CoreResampleCoefficientsTest(PillowTestCase):
test_color = 254 test_color = 254
for size in range(400000, 400010, 2): for size in range(400000, 400010, 2):
i = Image.new('L', (size, 1), 0) i = Image.new("L", (size, 1), 0)
draw = ImageDraw.Draw(i) draw = ImageDraw.Draw(i)
draw.rectangle((0, 0, i.size[0] // 2 - 1, 0), test_color) draw.rectangle((0, 0, i.size[0] // 2 - 1, 0), test_color)
@ -365,7 +380,7 @@ class CoreResampleCoefficientsTest(PillowTestCase):
def test_nonzero_coefficients(self): def test_nonzero_coefficients(self):
# regression test for the wrong coefficients calculation # regression test for the wrong coefficients calculation
# due to bug https://github.com/python-pillow/Pillow/issues/2161 # due to bug https://github.com/python-pillow/Pillow/issues/2161
im = Image.new('RGBA', (1280, 1280), (0x20, 0x40, 0x60, 0xff)) im = Image.new("RGBA", (1280, 1280), (0x20, 0x40, 0x60, 0xFF))
histogram = im.resize((256, 256), Image.BICUBIC).histogram() histogram = im.resize((256, 256), Image.BICUBIC).histogram()
# first channel # first channel
@ -375,21 +390,26 @@ class CoreResampleCoefficientsTest(PillowTestCase):
# third channel # third channel
self.assertEqual(histogram[0x100 * 2 + 0x60], 0x10000) self.assertEqual(histogram[0x100 * 2 + 0x60], 0x10000)
# fourth channel # fourth channel
self.assertEqual(histogram[0x100 * 3 + 0xff], 0x10000) self.assertEqual(histogram[0x100 * 3 + 0xFF], 0x10000)
class CoreResampleBoxTest(PillowTestCase): class CoreResampleBoxTest(PillowTestCase):
def test_wrong_arguments(self): def test_wrong_arguments(self):
im = hopper() im = hopper()
for resample in (Image.NEAREST, Image.BOX, Image.BILINEAR, for resample in (
Image.HAMMING, Image.BICUBIC, Image.LANCZOS): Image.NEAREST,
Image.BOX,
Image.BILINEAR,
Image.HAMMING,
Image.BICUBIC,
Image.LANCZOS,
):
im.resize((32, 32), resample, (0, 0, im.width, im.height)) im.resize((32, 32), resample, (0, 0, im.width, im.height))
im.resize((32, 32), resample, (20, 20, im.width, im.height)) im.resize((32, 32), resample, (20, 20, im.width, im.height))
im.resize((32, 32), resample, (20, 20, 20, 100)) im.resize((32, 32), resample, (20, 20, 20, 100))
im.resize((32, 32), resample, (20, 20, 100, 20)) im.resize((32, 32), resample, (20, 20, 100, 20))
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError, "must be sequence of length 4"):
"must be sequence of length 4"):
im.resize((32, 32), resample, (im.width, im.height)) im.resize((32, 32), resample, (im.width, im.height))
with self.assertRaisesRegex(ValueError, "can't be negative"): with self.assertRaisesRegex(ValueError, "can't be negative"):
@ -420,8 +440,7 @@ class CoreResampleBoxTest(PillowTestCase):
for y0, y1 in split_range(dst_size[1], ytiles): for y0, y1 in split_range(dst_size[1], ytiles):
for x0, x1 in split_range(dst_size[0], xtiles): for x0, x1 in split_range(dst_size[0], xtiles):
box = (x0 * scale[0], y0 * scale[1], box = (x0 * scale[0], y0 * scale[1], x1 * scale[0], y1 * scale[1])
x1 * scale[0], y1 * scale[1])
tile = im.resize((x1 - x0, y1 - y0), Image.BICUBIC, box) tile = im.resize((x1 - x0, y1 - y0), Image.BICUBIC, box)
tiled.paste(tile, (x0, y0)) tiled.paste(tile, (x0, y0))
return tiled return tiled
@ -447,8 +466,7 @@ class CoreResampleBoxTest(PillowTestCase):
# Image.BOX emulates supersampling (480 / 8 = 60, 360 / 8 = 45) # Image.BOX emulates supersampling (480 / 8 = 60, 360 / 8 = 45)
supersampled = im.resize((60, 45), Image.BOX) supersampled = im.resize((60, 45), Image.BOX)
with_box = supersampled.resize(dst_size, Image.BICUBIC, with_box = supersampled.resize(dst_size, Image.BICUBIC, (0, 0, 59.125, 44.125))
(0, 0, 59.125, 44.125))
without_box = supersampled.resize(dst_size, Image.BICUBIC) without_box = supersampled.resize(dst_size, Image.BICUBIC)
# error with box should be much smaller than without # error with box should be much smaller than without
@ -458,7 +476,7 @@ class CoreResampleBoxTest(PillowTestCase):
def test_formats(self): def test_formats(self):
for resample in [Image.NEAREST, Image.BILINEAR]: for resample in [Image.NEAREST, Image.BILINEAR]:
for mode in ['RGB', 'L', 'RGBA', 'LA', 'I', '']: for mode in ["RGB", "L", "RGBA", "LA", "I", ""]:
im = hopper(mode) im = hopper(mode)
box = (20, 20, im.size[0] - 20, im.size[1] - 20) box = (20, 20, im.size[0] - 20, im.size[1] - 20)
with_box = im.resize((32, 32), resample, box) with_box = im.resize((32, 32), resample, box)
@ -480,7 +498,7 @@ class CoreResampleBoxTest(PillowTestCase):
self.assertEqual(res.size, size) self.assertEqual(res.size, size)
self.assert_image_equal(res, im.crop(box)) self.assert_image_equal(res, im.crop(box))
except AssertionError: except AssertionError:
print('>>>', size, box) print(">>>", size, box)
raise raise
def test_no_passthrough(self): def test_no_passthrough(self):
@ -500,7 +518,7 @@ class CoreResampleBoxTest(PillowTestCase):
# check that the difference at least that much # check that the difference at least that much
self.assert_image_similar(res, im.crop(box), 20) self.assert_image_similar(res, im.crop(box), 20)
except AssertionError: except AssertionError:
print('>>>', size, box) print(">>>", size, box)
raise raise
def test_skip_horizontal(self): def test_skip_horizontal(self):
@ -518,10 +536,9 @@ class CoreResampleBoxTest(PillowTestCase):
res = im.resize(size, flt, box) res = im.resize(size, flt, box)
self.assertEqual(res.size, size) self.assertEqual(res.size, size)
# Borders should be slightly different # Borders should be slightly different
self.assert_image_similar( self.assert_image_similar(res, im.crop(box).resize(size, flt), 0.4)
res, im.crop(box).resize(size, flt), 0.4)
except AssertionError: except AssertionError:
print('>>>', size, box, flt) print(">>>", size, box, flt)
raise raise
def test_skip_vertical(self): def test_skip_vertical(self):
@ -539,8 +556,7 @@ class CoreResampleBoxTest(PillowTestCase):
res = im.resize(size, flt, box) res = im.resize(size, flt, box)
self.assertEqual(res.size, size) self.assertEqual(res.size, size)
# Borders should be slightly different # Borders should be slightly different
self.assert_image_similar( self.assert_image_similar(res, im.crop(box).resize(size, flt), 0.4)
res, im.crop(box).resize(size, flt), 0.4)
except AssertionError: except AssertionError:
print('>>>', size, box, flt) print(">>>", size, box, flt)
raise raise

View File

@ -9,15 +9,24 @@ from PIL import Image
class TestImagingCoreResize(PillowTestCase): class TestImagingCoreResize(PillowTestCase):
def resize(self, im, size, f): def resize(self, im, size, f):
# Image class independent version of resize. # Image class independent version of resize.
im.load() im.load()
return im._new(im.im.resize(size, f)) return im._new(im.im.resize(size, f))
def test_nearest_mode(self): def test_nearest_mode(self):
for mode in ["1", "P", "L", "I", "F", "RGB", "RGBA", "CMYK", "YCbCr", for mode in [
"I;16"]: # exotic mode "1",
"P",
"L",
"I",
"F",
"RGB",
"RGBA",
"CMYK",
"YCbCr",
"I;16",
]: # exotic mode
im = hopper(mode) im = hopper(mode)
r = self.resize(im, (15, 12), Image.NEAREST) r = self.resize(im, (15, 12), Image.NEAREST)
self.assertEqual(r.mode, mode) self.assertEqual(r.mode, mode)
@ -25,12 +34,15 @@ class TestImagingCoreResize(PillowTestCase):
self.assertEqual(r.im.bands, im.im.bands) self.assertEqual(r.im.bands, im.im.bands)
def test_convolution_modes(self): def test_convolution_modes(self):
self.assertRaises(ValueError, self.resize, hopper("1"), self.assertRaises(
(15, 12), Image.BILINEAR) ValueError, self.resize, hopper("1"), (15, 12), Image.BILINEAR
self.assertRaises(ValueError, self.resize, hopper("P"), )
(15, 12), Image.BILINEAR) self.assertRaises(
self.assertRaises(ValueError, self.resize, hopper("I;16"), ValueError, self.resize, hopper("P"), (15, 12), Image.BILINEAR
(15, 12), Image.BILINEAR) )
self.assertRaises(
ValueError, self.resize, hopper("I;16"), (15, 12), Image.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.BILINEAR) r = self.resize(im, (15, 12), Image.BILINEAR)
@ -39,15 +51,27 @@ class TestImagingCoreResize(PillowTestCase):
self.assertEqual(r.im.bands, im.im.bands) self.assertEqual(r.im.bands, im.im.bands)
def test_reduce_filters(self): def test_reduce_filters(self):
for f in [Image.NEAREST, Image.BOX, Image.BILINEAR, for f in [
Image.HAMMING, Image.BICUBIC, Image.LANCZOS]: Image.NEAREST,
Image.BOX,
Image.BILINEAR,
Image.HAMMING,
Image.BICUBIC,
Image.LANCZOS,
]:
r = self.resize(hopper("RGB"), (15, 12), f) r = self.resize(hopper("RGB"), (15, 12), f)
self.assertEqual(r.mode, "RGB") self.assertEqual(r.mode, "RGB")
self.assertEqual(r.size, (15, 12)) self.assertEqual(r.size, (15, 12))
def test_enlarge_filters(self): def test_enlarge_filters(self):
for f in [Image.NEAREST, Image.BOX, Image.BILINEAR, for f in [
Image.HAMMING, Image.BICUBIC, Image.LANCZOS]: Image.NEAREST,
Image.BOX,
Image.BILINEAR,
Image.HAMMING,
Image.BICUBIC,
Image.LANCZOS,
]:
r = self.resize(hopper("RGB"), (212, 195), f) r = self.resize(hopper("RGB"), (212, 195), f)
self.assertEqual(r.mode, "RGB") self.assertEqual(r.mode, "RGB")
self.assertEqual(r.size, (212, 195)) self.assertEqual(r.size, (212, 195))
@ -60,24 +84,29 @@ class TestImagingCoreResize(PillowTestCase):
# an endianness issues. # an endianness issues.
samples = { samples = {
'blank': Image.new('L', (2, 2), 0), "blank": Image.new("L", (2, 2), 0),
'filled': Image.new('L', (2, 2), 255), "filled": Image.new("L", (2, 2), 255),
'dirty': Image.new('L', (2, 2), 0), "dirty": Image.new("L", (2, 2), 0),
} }
samples['dirty'].putpixel((1, 1), 128) samples["dirty"].putpixel((1, 1), 128)
for f in [Image.NEAREST, Image.BOX, Image.BILINEAR, for f in [
Image.HAMMING, Image.BICUBIC, Image.LANCZOS]: Image.NEAREST,
Image.BOX,
Image.BILINEAR,
Image.HAMMING,
Image.BICUBIC,
Image.LANCZOS,
]:
# samples resized with current filter # samples resized with current filter
references = { references = {
name: self.resize(ch, (4, 4), f) name: self.resize(ch, (4, 4), f) for name, ch in samples.items()
for name, ch in samples.items()
} }
for mode, channels_set in [ for mode, channels_set in [
('RGB', ('blank', 'filled', 'dirty')), ("RGB", ("blank", "filled", "dirty")),
('RGBA', ('blank', 'blank', 'filled', 'dirty')), ("RGBA", ("blank", "blank", "filled", "dirty")),
('LA', ('filled', 'dirty')), ("LA", ("filled", "dirty")),
]: ]:
for channels in set(permutations(channels_set)): for channels in set(permutations(channels_set)):
# compile image from different channels permutations # compile image from different channels permutations
@ -90,9 +119,15 @@ class TestImagingCoreResize(PillowTestCase):
self.assert_image_equal(ch, references[channels[i]]) self.assert_image_equal(ch, references[channels[i]])
def test_enlarge_zero(self): def test_enlarge_zero(self):
for f in [Image.NEAREST, Image.BOX, Image.BILINEAR, for f in [
Image.HAMMING, Image.BICUBIC, Image.LANCZOS]: Image.NEAREST,
r = self.resize(Image.new('RGB', (0, 0), "white"), (212, 195), f) Image.BOX,
Image.BILINEAR,
Image.HAMMING,
Image.BICUBIC,
Image.LANCZOS,
]:
r = self.resize(Image.new("RGB", (0, 0), "white"), (212, 195), f)
self.assertEqual(r.mode, "RGB") self.assertEqual(r.mode, "RGB")
self.assertEqual(r.size, (212, 195)) self.assertEqual(r.size, (212, 195))
self.assertEqual(r.getdata()[0], (0, 0, 0)) self.assertEqual(r.getdata()[0], (0, 0, 0))
@ -102,12 +137,12 @@ class TestImagingCoreResize(PillowTestCase):
class TestImageResize(PillowTestCase): class TestImageResize(PillowTestCase):
def test_resize(self): def test_resize(self):
def resize(mode, size): def resize(mode, size):
out = hopper(mode).resize(size) out = hopper(mode).resize(size)
self.assertEqual(out.mode, mode) self.assertEqual(out.mode, mode)
self.assertEqual(out.size, size) self.assertEqual(out.size, size)
for mode in "1", "P", "L", "RGB", "I", "F": for mode in "1", "P", "L", "RGB", "I", "F":
resize(mode, (112, 103)) resize(mode, (112, 103))
resize(mode, (188, 214)) resize(mode, (188, 214))

View File

@ -3,7 +3,6 @@ from PIL import Image
class TestImageRotate(PillowTestCase): class TestImageRotate(PillowTestCase):
def rotate(self, im, mode, angle, center=None, translate=None): def rotate(self, im, mode, angle, center=None, translate=None):
out = im.rotate(angle, center=center, translate=translate) out = im.rotate(angle, center=center, translate=translate)
self.assertEqual(out.mode, mode) self.assertEqual(out.mode, mode)
@ -24,12 +23,12 @@ class TestImageRotate(PillowTestCase):
def test_angle(self): def test_angle(self):
for angle in (0, 90, 180, 270): for angle in (0, 90, 180, 270):
im = Image.open('Tests/images/test-card.png') im = Image.open("Tests/images/test-card.png")
self.rotate(im, im.mode, angle) self.rotate(im, im.mode, angle)
def test_zero(self): def test_zero(self):
for angle in (0, 45, 90, 180, 270): for angle in (0, 45, 90, 180, 270):
im = Image.new('RGB', (0, 0)) im = Image.new("RGB", (0, 0))
self.rotate(im, im.mode, angle) self.rotate(im, im.mode, angle)
def test_resample(self): def test_resample(self):
@ -38,18 +37,20 @@ class TestImageRotate(PillowTestCase):
# >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True) # >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True)
# >>> im.save('Tests/images/hopper_45.png') # >>> im.save('Tests/images/hopper_45.png')
target = Image.open('Tests/images/hopper_45.png') target = Image.open("Tests/images/hopper_45.png")
for (resample, epsilon) in ((Image.NEAREST, 10), for (resample, epsilon) in (
(Image.BILINEAR, 5), (Image.NEAREST, 10),
(Image.BICUBIC, 0)): (Image.BILINEAR, 5),
(Image.BICUBIC, 0),
):
im = hopper() im = hopper()
im = im.rotate(45, resample=resample, expand=True) im = im.rotate(45, resample=resample, expand=True)
self.assert_image_similar(im, target, epsilon) self.assert_image_similar(im, target, epsilon)
def test_center_0(self): def test_center_0(self):
im = hopper() im = hopper()
target = Image.open('Tests/images/hopper_45.png') target = Image.open("Tests/images/hopper_45.png")
target_origin = target.size[1]/2 target_origin = target.size[1] / 2
target = target.crop((0, target_origin, 128, target_origin + 128)) target = target.crop((0, target_origin, 128, target_origin + 128))
im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC) im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC)
@ -58,7 +59,7 @@ class TestImageRotate(PillowTestCase):
def test_center_14(self): def test_center_14(self):
im = hopper() im = hopper()
target = Image.open('Tests/images/hopper_45.png') target = Image.open("Tests/images/hopper_45.png")
target_origin = target.size[1] / 2 - 14 target_origin = target.size[1] / 2 - 14
target = target.crop((6, target_origin, 128 + 6, target_origin + 128)) target = target.crop((6, target_origin, 128 + 6, target_origin + 128))
@ -68,10 +69,11 @@ class TestImageRotate(PillowTestCase):
def test_translate(self): def test_translate(self):
im = hopper() im = hopper()
target = Image.open('Tests/images/hopper_45.png') target = Image.open("Tests/images/hopper_45.png")
target_origin = (target.size[1] / 2 - 64) - 5 target_origin = (target.size[1] / 2 - 64) - 5
target = target.crop((target_origin, target_origin, target = target.crop(
target_origin + 128, target_origin + 128)) (target_origin, target_origin, target_origin + 128, target_origin + 128)
)
im = im.rotate(45, translate=(5, 5), resample=Image.BICUBIC) im = im.rotate(45, translate=(5, 5), resample=Image.BICUBIC)
@ -82,44 +84,43 @@ class TestImageRotate(PillowTestCase):
# resulting image should be black # resulting image should be black
for angle in (90, 180, 270): for angle in (90, 180, 270):
im = hopper().rotate(angle, center=(-1, -1)) im = hopper().rotate(angle, center=(-1, -1))
self.assert_image_equal(im, Image.new('RGB', im.size, 'black')) self.assert_image_equal(im, Image.new("RGB", im.size, "black"))
def test_fastpath_translate(self): def test_fastpath_translate(self):
# if we post-translate by -128 # if we post-translate by -128
# resulting image should be black # resulting image should be black
for angle in (0, 90, 180, 270): for angle in (0, 90, 180, 270):
im = hopper().rotate(angle, translate=(-128, -128)) im = hopper().rotate(angle, translate=(-128, -128))
self.assert_image_equal(im, Image.new('RGB', im.size, 'black')) self.assert_image_equal(im, Image.new("RGB", im.size, "black"))
def test_center(self): def test_center(self):
im = hopper() im = hopper()
self.rotate(im, im.mode, 45, center=(0, 0)) self.rotate(im, im.mode, 45, center=(0, 0))
self.rotate(im, im.mode, 45, translate=(im.size[0]/2, 0)) self.rotate(im, im.mode, 45, translate=(im.size[0] / 2, 0))
self.rotate(im, im.mode, 45, center=(0, 0), self.rotate(im, im.mode, 45, center=(0, 0), translate=(im.size[0] / 2, 0))
translate=(im.size[0]/2, 0))
def test_rotate_no_fill(self): def test_rotate_no_fill(self):
im = Image.new('RGB', (100, 100), 'green') im = Image.new("RGB", (100, 100), "green")
target = Image.open('Tests/images/rotate_45_no_fill.png') target = Image.open("Tests/images/rotate_45_no_fill.png")
im = im.rotate(45) im = im.rotate(45)
self.assert_image_equal(im, target) self.assert_image_equal(im, target)
def test_rotate_with_fill(self): def test_rotate_with_fill(self):
im = Image.new('RGB', (100, 100), 'green') im = Image.new("RGB", (100, 100), "green")
target = Image.open('Tests/images/rotate_45_with_fill.png') target = Image.open("Tests/images/rotate_45_with_fill.png")
im = im.rotate(45, fillcolor='white') im = im.rotate(45, fillcolor="white")
self.assert_image_equal(im, target) self.assert_image_equal(im, target)
def test_alpha_rotate_no_fill(self): def test_alpha_rotate_no_fill(self):
# Alpha images are handled differently internally # Alpha images are handled differently internally
im = Image.new('RGBA', (10, 10), 'green') im = Image.new("RGBA", (10, 10), "green")
im = im.rotate(45, expand=1) im = im.rotate(45, expand=1)
corner = im.getpixel((0, 0)) corner = im.getpixel((0, 0))
self.assertEqual(corner, (0, 0, 0, 0)) self.assertEqual(corner, (0, 0, 0, 0))
def test_alpha_rotate_with_fill(self): def test_alpha_rotate_with_fill(self):
# Alpha images are handled differently internally # Alpha images are handled differently internally
im = Image.new('RGBA', (10, 10), 'green') im = Image.new("RGBA", (10, 10), "green")
im = im.rotate(45, expand=1, fillcolor=(255, 0, 0, 255)) im = im.rotate(45, expand=1, fillcolor=(255, 0, 0, 255))
corner = im.getpixel((0, 0)) corner = im.getpixel((0, 0))
self.assertEqual(corner, (255, 0, 0, 255)) self.assertEqual(corner, (255, 0, 0, 255))

View File

@ -4,33 +4,35 @@ from PIL import Image
class TestImageSplit(PillowTestCase): class TestImageSplit(PillowTestCase):
def test_split(self): def test_split(self):
def split(mode): def split(mode):
layers = hopper(mode).split() layers = hopper(mode).split()
return [(i.mode, i.size[0], i.size[1]) for i in layers] return [(i.mode, i.size[0], i.size[1]) for i in layers]
self.assertEqual(split("1"), [('1', 128, 128)])
self.assertEqual(split("L"), [('L', 128, 128)]) self.assertEqual(split("1"), [("1", 128, 128)])
self.assertEqual(split("I"), [('I', 128, 128)]) self.assertEqual(split("L"), [("L", 128, 128)])
self.assertEqual(split("F"), [('F', 128, 128)]) self.assertEqual(split("I"), [("I", 128, 128)])
self.assertEqual(split("P"), [('P', 128, 128)]) self.assertEqual(split("F"), [("F", 128, 128)])
self.assertEqual(split("P"), [("P", 128, 128)])
self.assertEqual( self.assertEqual(
split("RGB"), [('L', 128, 128), ('L', 128, 128), ('L', 128, 128)]) split("RGB"), [("L", 128, 128), ("L", 128, 128), ("L", 128, 128)]
)
self.assertEqual( self.assertEqual(
split("RGBA"), split("RGBA"),
[('L', 128, 128), ('L', 128, 128), [("L", 128, 128), ("L", 128, 128), ("L", 128, 128), ("L", 128, 128)],
('L', 128, 128), ('L', 128, 128)]) )
self.assertEqual( self.assertEqual(
split("CMYK"), split("CMYK"),
[('L', 128, 128), ('L', 128, 128), [("L", 128, 128), ("L", 128, 128), ("L", 128, 128), ("L", 128, 128)],
('L', 128, 128), ('L', 128, 128)]) )
self.assertEqual( self.assertEqual(
split("YCbCr"), split("YCbCr"), [("L", 128, 128), ("L", 128, 128), ("L", 128, 128)]
[('L', 128, 128), ('L', 128, 128), ('L', 128, 128)]) )
def test_split_merge(self): def test_split_merge(self):
def split_merge(mode): def split_merge(mode):
return Image.merge(mode, hopper(mode).split()) return Image.merge(mode, hopper(mode).split())
self.assert_image_equal(hopper("1"), split_merge("1")) self.assert_image_equal(hopper("1"), split_merge("1"))
self.assert_image_equal(hopper("L"), split_merge("L")) self.assert_image_equal(hopper("L"), split_merge("L"))
self.assert_image_equal(hopper("I"), split_merge("I")) self.assert_image_equal(hopper("I"), split_merge("I"))
@ -44,7 +46,7 @@ class TestImageSplit(PillowTestCase):
def test_split_open(self): def test_split_open(self):
codecs = dir(Image.core) codecs = dir(Image.core)
if 'zip_encoder' in codecs: if "zip_encoder" in codecs:
test_file = self.tempfile("temp.png") test_file = self.tempfile("temp.png")
else: else:
test_file = self.tempfile("temp.pcx") test_file = self.tempfile("temp.pcx")
@ -53,9 +55,10 @@ class TestImageSplit(PillowTestCase):
hopper(mode).save(test_file) hopper(mode).save(test_file)
im = Image.open(test_file) im = Image.open(test_file)
return len(im.split()) return len(im.split())
self.assertEqual(split_open("1"), 1) self.assertEqual(split_open("1"), 1)
self.assertEqual(split_open("L"), 1) self.assertEqual(split_open("L"), 1)
self.assertEqual(split_open("P"), 1) self.assertEqual(split_open("P"), 1)
self.assertEqual(split_open("RGB"), 3) self.assertEqual(split_open("RGB"), 3)
if 'zip_encoder' in codecs: if "zip_encoder" in codecs:
self.assertEqual(split_open("RGBA"), 4) self.assertEqual(split_open("RGBA"), 4)

View File

@ -3,7 +3,6 @@ from PIL import Image
class TestImageThumbnail(PillowTestCase): class TestImageThumbnail(PillowTestCase):
def test_sanity(self): def test_sanity(self):
im = hopper() im = hopper()

View File

@ -2,7 +2,6 @@ from .helper import PillowTestCase, hopper, fromstring
class TestImageToBitmap(PillowTestCase): class TestImageToBitmap(PillowTestCase):
def test_sanity(self): def test_sanity(self):
self.assertRaises(ValueError, lambda: hopper().tobitmap()) self.assertRaises(ValueError, lambda: hopper().tobitmap())

View File

@ -2,7 +2,6 @@ from .helper import PillowTestCase, hopper
class TestImageToBytes(PillowTestCase): class TestImageToBytes(PillowTestCase):
def test_sanity(self): def test_sanity(self):
data = hopper().tobytes() data = hopper().tobytes()
self.assertIsInstance(data, bytes) self.assertIsInstance(data, bytes)

View File

@ -6,7 +6,6 @@ from PIL import Image
class TestImageTransform(PillowTestCase): class TestImageTransform(PillowTestCase):
def test_sanity(self): def test_sanity(self):
from PIL import ImageTransform from PIL import ImageTransform
@ -24,54 +23,61 @@ class TestImageTransform(PillowTestCase):
im.transform((100, 100), transform) im.transform((100, 100), transform)
def test_extent(self): def test_extent(self):
im = hopper('RGB') im = hopper("RGB")
(w, h) = im.size (w, h) = im.size
# fmt: off
transformed = im.transform(im.size, Image.EXTENT, transformed = im.transform(im.size, Image.EXTENT,
(0, 0, (0, 0,
w//2, h//2), # ul -> lr w//2, h//2), # ul -> lr
Image.BILINEAR) Image.BILINEAR)
# fmt: on
scaled = im.resize((w*2, h*2), Image.BILINEAR).crop((0, 0, w, h)) scaled = im.resize((w * 2, h * 2), Image.BILINEAR).crop((0, 0, w, h))
# undone -- precision? # undone -- precision?
self.assert_image_similar(transformed, scaled, 23) self.assert_image_similar(transformed, scaled, 23)
def test_quad(self): def test_quad(self):
# one simple quad transform, equivalent to scale & crop upper left quad # one simple quad transform, equivalent to scale & crop upper left quad
im = hopper('RGB') im = hopper("RGB")
(w, h) = im.size (w, h) = im.size
# fmt: off
transformed = im.transform(im.size, Image.QUAD, transformed = im.transform(im.size, Image.QUAD,
(0, 0, 0, h//2, (0, 0, 0, h//2,
# ul -> ccw around quad: # ul -> ccw around quad:
w//2, h//2, w//2, 0), w//2, h//2, w//2, 0),
Image.BILINEAR) Image.BILINEAR)
# fmt: on
scaled = im.transform((w, h), Image.AFFINE, scaled = im.transform(
(.5, 0, 0, 0, .5, 0), (w, h), Image.AFFINE, (0.5, 0, 0, 0, 0.5, 0), Image.BILINEAR
Image.BILINEAR) )
self.assert_image_equal(transformed, scaled) self.assert_image_equal(transformed, scaled)
def test_fill(self): def test_fill(self):
for mode, pixel in [ for mode, pixel in [
['RGB', (255, 0, 0)], ["RGB", (255, 0, 0)],
['RGBA', (255, 0, 0, 255)], ["RGBA", (255, 0, 0, 255)],
['LA', (76, 0)] ["LA", (76, 0)],
]: ]:
im = hopper(mode) im = hopper(mode)
(w, h) = im.size (w, h) = im.size
transformed = im.transform(im.size, Image.EXTENT, transformed = im.transform(
(0, 0, im.size,
w*2, h*2), Image.EXTENT,
Image.BILINEAR, (0, 0, w * 2, h * 2),
fillcolor='red') Image.BILINEAR,
fillcolor="red",
)
self.assertEqual(transformed.getpixel((w-1, h-1)), pixel) self.assertEqual(transformed.getpixel((w - 1, h - 1)), pixel)
def test_mesh(self): def test_mesh(self):
# this should be a checkerboard of halfsized hoppers in ul, lr # this should be a checkerboard of halfsized hoppers in ul, lr
im = hopper('RGBA') im = hopper("RGBA")
(w, h) = im.size (w, h) = im.size
# fmt: off
transformed = im.transform(im.size, Image.MESH, transformed = im.transform(im.size, Image.MESH,
[((0, 0, w//2, h//2), # box [((0, 0, w//2, h//2), # box
(0, 0, 0, h, (0, 0, 0, h,
@ -80,54 +86,50 @@ class TestImageTransform(PillowTestCase):
(0, 0, 0, h, (0, 0, 0, h,
w, h, w, 0))], # ul -> ccw around quad w, h, w, 0))], # ul -> ccw around quad
Image.BILINEAR) Image.BILINEAR)
# fmt: on
scaled = im.transform((w//2, h//2), Image.AFFINE, scaled = im.transform(
(2, 0, 0, 0, 2, 0), (w // 2, h // 2), Image.AFFINE, (2, 0, 0, 0, 2, 0), Image.BILINEAR
Image.BILINEAR) )
checker = Image.new('RGBA', im.size) checker = Image.new("RGBA", im.size)
checker.paste(scaled, (0, 0)) checker.paste(scaled, (0, 0))
checker.paste(scaled, (w//2, h//2)) checker.paste(scaled, (w // 2, h // 2))
self.assert_image_equal(transformed, checker) self.assert_image_equal(transformed, checker)
# now, check to see that the extra area is (0, 0, 0, 0) # now, check to see that the extra area is (0, 0, 0, 0)
blank = Image.new('RGBA', (w//2, h//2), (0, 0, 0, 0)) blank = Image.new("RGBA", (w // 2, h // 2), (0, 0, 0, 0))
self.assert_image_equal(blank, transformed.crop((w//2, 0, w, h//2))) self.assert_image_equal(blank, transformed.crop((w // 2, 0, w, h // 2)))
self.assert_image_equal(blank, transformed.crop((0, h//2, w//2, h))) self.assert_image_equal(blank, transformed.crop((0, h // 2, w // 2, h)))
def _test_alpha_premult(self, op): def _test_alpha_premult(self, op):
# create image with half white, half black, # create image with half white, half black,
# with the black half transparent. # with the black half transparent.
# do op, # do op,
# there should be no darkness in the white section. # there should be no darkness in the white section.
im = Image.new('RGBA', (10, 10), (0, 0, 0, 0)) im = Image.new("RGBA", (10, 10), (0, 0, 0, 0))
im2 = Image.new('RGBA', (5, 10), (255, 255, 255, 255)) im2 = Image.new("RGBA", (5, 10), (255, 255, 255, 255))
im.paste(im2, (0, 0)) im.paste(im2, (0, 0))
im = op(im, (40, 10)) im = op(im, (40, 10))
im_background = Image.new('RGB', (40, 10), (255, 255, 255)) im_background = Image.new("RGB", (40, 10), (255, 255, 255))
im_background.paste(im, (0, 0), im) im_background.paste(im, (0, 0), im)
hist = im_background.histogram() hist = im_background.histogram()
self.assertEqual(40*10, hist[-1]) self.assertEqual(40 * 10, hist[-1])
def test_alpha_premult_resize(self): def test_alpha_premult_resize(self):
def op(im, sz): def op(im, sz):
return im.resize(sz, Image.BILINEAR) return im.resize(sz, Image.BILINEAR)
self._test_alpha_premult(op) self._test_alpha_premult(op)
def test_alpha_premult_transform(self): def test_alpha_premult_transform(self):
def op(im, sz): def op(im, sz):
(w, h) = im.size (w, h) = im.size
return im.transform(sz, Image.EXTENT, return im.transform(sz, Image.EXTENT, (0, 0, w, h), Image.BILINEAR)
(0, 0,
w, h),
Image.BILINEAR)
self._test_alpha_premult(op) self._test_alpha_premult(op)
@ -146,10 +148,7 @@ class TestImageTransform(PillowTestCase):
# Running by default, but I'd totally understand not doing it in # Running by default, but I'd totally understand not doing it in
# the future # the future
pattern = [ pattern = [Image.new("RGBA", (1024, 1024), (a, a, a, a)) for a in range(1, 65)]
Image.new('RGBA', (1024, 1024), (a, a, a, a))
for a in range(1, 65)
]
# Yeah. Watch some JIT optimize this out. # Yeah. Watch some JIT optimize this out.
pattern = None # noqa: F841 pattern = None # noqa: F841
@ -164,27 +163,37 @@ class TestImageTransform(PillowTestCase):
im = hopper() im = hopper()
(w, h) = im.size (w, h) = im.size
for resample in (Image.BOX, "unknown"): for resample in (Image.BOX, "unknown"):
self.assertRaises(ValueError, im.transform, (100, 100), Image.EXTENT, self.assertRaises(
(0, 0, ValueError,
w, h), im.transform,
resample) (100, 100),
Image.EXTENT,
(0, 0, w, h),
resample,
)
class TestImageTransformAffine(PillowTestCase): class TestImageTransformAffine(PillowTestCase):
transform = Image.AFFINE transform = Image.AFFINE
def _test_image(self): def _test_image(self):
im = hopper('RGB') im = hopper("RGB")
return im.crop((10, 20, im.width - 10, im.height - 20)) return im.crop((10, 20, im.width - 10, im.height - 20))
def _test_rotate(self, deg, transpose): def _test_rotate(self, deg, transpose):
im = self._test_image() im = self._test_image()
angle = - math.radians(deg) angle = -math.radians(deg)
matrix = [ matrix = [
round(math.cos(angle), 15), round(math.sin(angle), 15), 0.0, round(math.cos(angle), 15),
round(-math.sin(angle), 15), round(math.cos(angle), 15), 0.0, round(math.sin(angle), 15),
0, 0] 0.0,
round(-math.sin(angle), 15),
round(math.cos(angle), 15),
0.0,
0,
0,
]
matrix[2] = (1 - matrix[0] - matrix[1]) * im.width / 2 matrix[2] = (1 - matrix[0] - matrix[1]) * im.width / 2
matrix[5] = (1 - matrix[3] - matrix[4]) * im.height / 2 matrix[5] = (1 - matrix[3] - matrix[4]) * im.height / 2
@ -194,8 +203,9 @@ class TestImageTransformAffine(PillowTestCase):
transposed = im transposed = im
for resample in [Image.NEAREST, Image.BILINEAR, Image.BICUBIC]: for resample in [Image.NEAREST, Image.BILINEAR, Image.BICUBIC]:
transformed = im.transform(transposed.size, self.transform, transformed = im.transform(
matrix, resample) transposed.size, self.transform, matrix, resample
)
self.assert_image_equal(transposed, transformed) self.assert_image_equal(transposed, transformed)
def test_rotate_0_deg(self): def test_rotate_0_deg(self):
@ -214,21 +224,18 @@ class TestImageTransformAffine(PillowTestCase):
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 = [ matrix_up = [1 / scale, 0, 0, 0, 1 / scale, 0, 0, 0]
1 / scale, 0, 0, matrix_down = [scale, 0, 0, 0, scale, 0, 0, 0]
0, 1 / scale, 0,
0, 0]
matrix_down = [
scale, 0, 0,
0, scale, 0,
0, 0]
for resample, epsilon in [(Image.NEAREST, 0), for resample, epsilon in [
(Image.BILINEAR, 2), (Image.BICUBIC, 1)]: (Image.NEAREST, 0),
transformed = im.transform( (Image.BILINEAR, 2),
size_up, self.transform, matrix_up, resample) (Image.BICUBIC, 1),
]:
transformed = im.transform(size_up, self.transform, matrix_up, resample)
transformed = transformed.transform( transformed = transformed.transform(
im.size, self.transform, matrix_down, resample) im.size, self.transform, matrix_down, resample
)
self.assert_image_similar(transformed, im, epsilon * epsilonscale) self.assert_image_similar(transformed, im, epsilon * epsilonscale)
def test_resize_1_1x(self): def test_resize_1_1x(self):
@ -250,28 +257,25 @@ class TestImageTransformAffine(PillowTestCase):
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 = [ matrix_up = [1, 0, -x, 0, 1, -y, 0, 0]
1, 0, -x, matrix_down = [1, 0, x, 0, 1, y, 0, 0]
0, 1, -y,
0, 0]
matrix_down = [
1, 0, x,
0, 1, y,
0, 0]
for resample, epsilon in [(Image.NEAREST, 0), for resample, epsilon in [
(Image.BILINEAR, 1.5), (Image.BICUBIC, 1)]: (Image.NEAREST, 0),
transformed = im.transform( (Image.BILINEAR, 1.5),
size_up, self.transform, matrix_up, resample) (Image.BICUBIC, 1),
]:
transformed = im.transform(size_up, self.transform, matrix_up, resample)
transformed = transformed.transform( transformed = transformed.transform(
im.size, self.transform, matrix_down, resample) im.size, self.transform, matrix_down, resample
)
self.assert_image_similar(transformed, im, epsilon * epsilonscale) self.assert_image_similar(transformed, im, epsilon * epsilonscale)
def test_translate_0_1(self): def test_translate_0_1(self):
self._test_translate(.1, 0, 3.7) self._test_translate(0.1, 0, 3.7)
def test_translate_0_6(self): def test_translate_0_6(self):
self._test_translate(.6, 0, 9.1) self._test_translate(0.6, 0, 9.1)
def test_translate_50(self): def test_translate_50(self):
self._test_translate(50, 50, 0) self._test_translate(50, 50, 0)

View File

@ -1,15 +1,23 @@
from . import helper from . import helper
from .helper import PillowTestCase from .helper import PillowTestCase
from PIL.Image import (FLIP_LEFT_RIGHT, FLIP_TOP_BOTTOM, ROTATE_90, ROTATE_180, from PIL.Image import (
ROTATE_270, TRANSPOSE, TRANSVERSE) FLIP_LEFT_RIGHT,
FLIP_TOP_BOTTOM,
ROTATE_90,
ROTATE_180,
ROTATE_270,
TRANSPOSE,
TRANSVERSE,
)
class TestImageTranspose(PillowTestCase): class TestImageTranspose(PillowTestCase):
hopper = {mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy() for mode in [ hopper = {
'L', 'RGB', 'I;16', 'I;16L', 'I;16B' mode: helper.hopper(mode).crop((0, 0, 121, 127)).copy()
]} for mode in ["L", "RGB", "I;16", "I;16L", "I;16B"]
}
def test_flip_left_right(self): def test_flip_left_right(self):
def transpose(mode): def transpose(mode):
@ -19,10 +27,10 @@ class TestImageTranspose(PillowTestCase):
self.assertEqual(out.size, im.size) self.assertEqual(out.size, im.size)
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((x-2, 1))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((x - 2, 1)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, 1)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((x-2, y-2))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((x - 2, y - 2)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((1, y-2))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, y - 2)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -35,10 +43,10 @@ class TestImageTranspose(PillowTestCase):
self.assertEqual(out.size, im.size) self.assertEqual(out.size, im.size)
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, y-2))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, y - 2)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((x-2, y-2))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((x - 2, y - 2)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((1, 1)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((x-2, 1))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((x - 2, 1)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -51,10 +59,10 @@ class TestImageTranspose(PillowTestCase):
self.assertEqual(out.size, im.size[::-1]) self.assertEqual(out.size, im.size[::-1])
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, x-2))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, x - 2)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, 1)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((y-2, x-2))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((y - 2, x - 2)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((y-2, 1))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((y - 2, 1)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -67,10 +75,10 @@ class TestImageTranspose(PillowTestCase):
self.assertEqual(out.size, im.size) self.assertEqual(out.size, im.size)
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((x-2, y-2))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((x - 2, y - 2)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((1, y-2))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, y - 2)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((x-2, 1))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((x - 2, 1)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, 1)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -83,10 +91,10 @@ class TestImageTranspose(PillowTestCase):
self.assertEqual(out.size, im.size[::-1]) self.assertEqual(out.size, im.size[::-1])
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((y-2, 1))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((y - 2, 1)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((y-2, x-2))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((y - 2, x - 2)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((1, 1)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((1, x-2))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, x - 2)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -100,9 +108,9 @@ class TestImageTranspose(PillowTestCase):
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((1, 1)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((1, x-2))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((1, x - 2)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((y-2, 1))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((y - 2, 1)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((y-2, x-2))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((y - 2, x - 2)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -115,10 +123,10 @@ class TestImageTranspose(PillowTestCase):
self.assertEqual(out.size, im.size[::-1]) self.assertEqual(out.size, im.size[::-1])
x, y = im.size x, y = im.size
self.assertEqual(im.getpixel((1, 1)), out.getpixel((y-2, x-2))) self.assertEqual(im.getpixel((1, 1)), out.getpixel((y - 2, x - 2)))
self.assertEqual(im.getpixel((x-2, 1)), out.getpixel((y-2, 1))) self.assertEqual(im.getpixel((x - 2, 1)), out.getpixel((y - 2, 1)))
self.assertEqual(im.getpixel((1, y-2)), out.getpixel((1, x-2))) self.assertEqual(im.getpixel((1, y - 2)), out.getpixel((1, x - 2)))
self.assertEqual(im.getpixel((x-2, y-2)), out.getpixel((1, 1))) self.assertEqual(im.getpixel((x - 2, y - 2)), out.getpixel((1, 1)))
for mode in self.hopper: for mode in self.hopper:
transpose(mode) transpose(mode)
@ -130,19 +138,22 @@ class TestImageTranspose(PillowTestCase):
def transpose(first, second): def transpose(first, second):
return im.transpose(first).transpose(second) return im.transpose(first).transpose(second)
self.assert_image_equal( self.assert_image_equal(im, transpose(FLIP_LEFT_RIGHT, FLIP_LEFT_RIGHT))
im, transpose(FLIP_LEFT_RIGHT, FLIP_LEFT_RIGHT)) self.assert_image_equal(im, transpose(FLIP_TOP_BOTTOM, FLIP_TOP_BOTTOM))
self.assert_image_equal(
im, transpose(FLIP_TOP_BOTTOM, FLIP_TOP_BOTTOM))
self.assert_image_equal(im, transpose(ROTATE_90, ROTATE_270)) self.assert_image_equal(im, transpose(ROTATE_90, ROTATE_270))
self.assert_image_equal(im, transpose(ROTATE_180, ROTATE_180)) self.assert_image_equal(im, transpose(ROTATE_180, ROTATE_180))
self.assert_image_equal( self.assert_image_equal(
im.transpose(TRANSPOSE), transpose(ROTATE_90, FLIP_TOP_BOTTOM)) im.transpose(TRANSPOSE), transpose(ROTATE_90, FLIP_TOP_BOTTOM)
)
self.assert_image_equal( self.assert_image_equal(
im.transpose(TRANSPOSE), transpose(ROTATE_270, FLIP_LEFT_RIGHT)) im.transpose(TRANSPOSE), transpose(ROTATE_270, FLIP_LEFT_RIGHT)
)
self.assert_image_equal( self.assert_image_equal(
im.transpose(TRANSVERSE), transpose(ROTATE_90, FLIP_LEFT_RIGHT)) im.transpose(TRANSVERSE), transpose(ROTATE_90, FLIP_LEFT_RIGHT)
)
self.assert_image_equal( self.assert_image_equal(
im.transpose(TRANSVERSE), transpose(ROTATE_270, FLIP_TOP_BOTTOM)) im.transpose(TRANSVERSE), transpose(ROTATE_270, FLIP_TOP_BOTTOM)
)
self.assert_image_equal( self.assert_image_equal(
im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE)) im.transpose(TRANSVERSE), transpose(ROTATE_180, TRANSPOSE)
)