mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 02:16:19 +03:00
4de5477b61
With the introduction and use of pytest, it is simple and easy to execute specific tests in isolation through documented command line arguments. Either by specifying the module path or through the `-k EXPRESSION` argument. There is no longer any need to provide the boilerplate: if __name__ == '__main__': unittest.main() To every test file. It is simply noise. The pattern remains in test files that aren't named with `test_*` as those files are not discovered and executed by pytest by default.
522 lines
22 KiB
Python
522 lines
22 KiB
Python
from __future__ import division
|
|
|
|
from array import array
|
|
|
|
from PIL import Image, ImageFilter
|
|
from .helper import unittest, PillowTestCase
|
|
|
|
try:
|
|
import numpy
|
|
except ImportError:
|
|
numpy = None
|
|
|
|
|
|
class TestColorLut3DCoreAPI(PillowTestCase):
|
|
def generate_identity_table(self, channels, size):
|
|
if isinstance(size, tuple):
|
|
size1D, size2D, size3D = size
|
|
else:
|
|
size1D, size2D, size3D = (size, size, size)
|
|
|
|
table = [
|
|
[
|
|
r / float(size1D-1) if size1D != 1 else 0,
|
|
g / float(size2D-1) if size2D != 1 else 0,
|
|
b / float(size3D-1) if size3D != 1 else 0,
|
|
r / float(size1D-1) if size1D != 1 else 0,
|
|
g / float(size2D-1) if size2D != 1 else 0,
|
|
][:channels]
|
|
for b in range(size3D)
|
|
for g in range(size2D)
|
|
for r in range(size1D)
|
|
]
|
|
return (
|
|
channels, size1D, size2D, size3D,
|
|
[item for sublist in table for item in sublist])
|
|
|
|
def test_wrong_args(self):
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
|
|
with self.assertRaisesRegex(ValueError, "filter"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.CUBIC,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "image mode"):
|
|
im.im.color_lut_3d('wrong',
|
|
Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "table_channels"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
*self.generate_identity_table(5, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "table_channels"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
*self.generate_identity_table(1, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "table_channels"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
*self.generate_identity_table(2, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "Table size"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
*self.generate_identity_table(3, (1, 3, 3)))
|
|
|
|
with self.assertRaisesRegex(ValueError, "Table size"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
*self.generate_identity_table(3, (66, 3, 3)))
|
|
|
|
with self.assertRaisesRegex(ValueError, r"size1D \* size2D \* size3D"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
3, 2, 2, 2, [0, 0, 0] * 7)
|
|
|
|
with self.assertRaisesRegex(ValueError, r"size1D \* size2D \* size3D"):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
3, 2, 2, 2, [0, 0, 0] * 9)
|
|
|
|
with self.assertRaises(TypeError):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
3, 2, 2, 2, [0, 0, "0"] * 8)
|
|
|
|
with self.assertRaises(TypeError):
|
|
im.im.color_lut_3d('RGB',
|
|
Image.LINEAR,
|
|
3, 2, 2, 2, 16)
|
|
|
|
def test_correct_args(self):
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
im.im.color_lut_3d('CMYK', Image.LINEAR,
|
|
*self.generate_identity_table(4, 3))
|
|
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, (2, 3, 3)))
|
|
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, (65, 3, 3)))
|
|
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, (3, 65, 3)))
|
|
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, (3, 3, 65)))
|
|
|
|
def test_wrong_mode(self):
|
|
with self.assertRaisesRegex(ValueError, "wrong mode"):
|
|
im = Image.new('L', (10, 10), 0)
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "wrong mode"):
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
im.im.color_lut_3d('L', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "wrong mode"):
|
|
im = Image.new('L', (10, 10), 0)
|
|
im.im.color_lut_3d('L', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "wrong mode"):
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
im.im.color_lut_3d('RGBA', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
with self.assertRaisesRegex(ValueError, "wrong mode"):
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(4, 3))
|
|
|
|
def test_correct_mode(self):
|
|
im = Image.new('RGBA', (10, 10), 0)
|
|
im.im.color_lut_3d('RGBA', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
im = Image.new('RGBA', (10, 10), 0)
|
|
im.im.color_lut_3d('RGBA', Image.LINEAR,
|
|
*self.generate_identity_table(4, 3))
|
|
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
im.im.color_lut_3d('HSV', Image.LINEAR,
|
|
*self.generate_identity_table(3, 3))
|
|
|
|
im = Image.new('RGB', (10, 10), 0)
|
|
im.im.color_lut_3d('RGBA', Image.LINEAR,
|
|
*self.generate_identity_table(4, 3))
|
|
|
|
def test_identities(self):
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180)])
|
|
|
|
# Fast test with small cubes
|
|
for size in [2, 3, 5, 7, 11, 16, 17]:
|
|
self.assert_image_equal(im, im._new(
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, size))))
|
|
|
|
# Not so fast
|
|
self.assert_image_equal(im, im._new(
|
|
im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
*self.generate_identity_table(3, (2, 2, 65)))))
|
|
|
|
def test_identities_4_channels(self):
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180)])
|
|
|
|
# Red channel copied to alpha
|
|
self.assert_image_equal(
|
|
Image.merge('RGBA', (im.split()*2)[:4]),
|
|
im._new(im.im.color_lut_3d('RGBA', Image.LINEAR,
|
|
*self.generate_identity_table(4, 17))))
|
|
|
|
def test_copy_alpha_channel(self):
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGBA', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180),
|
|
g.transpose(Image.ROTATE_270)])
|
|
|
|
self.assert_image_equal(im, im._new(
|
|
im.im.color_lut_3d('RGBA', Image.LINEAR,
|
|
*self.generate_identity_table(3, 17))))
|
|
|
|
def test_channels_order(self):
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180)])
|
|
|
|
# Reverse channels by splitting and using table
|
|
self.assert_image_equal(
|
|
Image.merge('RGB', im.split()[::-1]),
|
|
im._new(im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
3, 2, 2, 2, [
|
|
0, 0, 0, 0, 0, 1,
|
|
0, 1, 0, 0, 1, 1,
|
|
|
|
1, 0, 0, 1, 0, 1,
|
|
1, 1, 0, 1, 1, 1,
|
|
])))
|
|
|
|
def test_overflow(self):
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180)])
|
|
|
|
transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
3, 2, 2, 2,
|
|
[
|
|
-1, -1, -1, 2, -1, -1,
|
|
-1, 2, -1, 2, 2, -1,
|
|
|
|
-1, -1, 2, 2, -1, 2,
|
|
-1, 2, 2, 2, 2, 2,
|
|
])).load()
|
|
self.assertEqual(transformed[0, 0], (0, 0, 255))
|
|
self.assertEqual(transformed[50, 50], (0, 0, 255))
|
|
self.assertEqual(transformed[255, 0], (0, 255, 255))
|
|
self.assertEqual(transformed[205, 50], (0, 255, 255))
|
|
self.assertEqual(transformed[0, 255], (255, 0, 0))
|
|
self.assertEqual(transformed[50, 205], (255, 0, 0))
|
|
self.assertEqual(transformed[255, 255], (255, 255, 0))
|
|
self.assertEqual(transformed[205, 205], (255, 255, 0))
|
|
|
|
transformed = im._new(im.im.color_lut_3d('RGB', Image.LINEAR,
|
|
3, 2, 2, 2,
|
|
[
|
|
-3, -3, -3, 5, -3, -3,
|
|
-3, 5, -3, 5, 5, -3,
|
|
|
|
-3, -3, 5, 5, -3, 5,
|
|
-3, 5, 5, 5, 5, 5,
|
|
])).load()
|
|
self.assertEqual(transformed[0, 0], (0, 0, 255))
|
|
self.assertEqual(transformed[50, 50], (0, 0, 255))
|
|
self.assertEqual(transformed[255, 0], (0, 255, 255))
|
|
self.assertEqual(transformed[205, 50], (0, 255, 255))
|
|
self.assertEqual(transformed[0, 255], (255, 0, 0))
|
|
self.assertEqual(transformed[50, 205], (255, 0, 0))
|
|
self.assertEqual(transformed[255, 255], (255, 255, 0))
|
|
self.assertEqual(transformed[205, 205], (255, 255, 0))
|
|
|
|
|
|
class TestColorLut3DFilter(PillowTestCase):
|
|
def test_wrong_args(self):
|
|
with self.assertRaisesRegex(ValueError, "should be either an integer"):
|
|
ImageFilter.Color3DLUT("small", [1])
|
|
|
|
with self.assertRaisesRegex(ValueError, "should be either an integer"):
|
|
ImageFilter.Color3DLUT((11, 11), [1])
|
|
|
|
with self.assertRaisesRegex(ValueError, r"in \[2, 65\] range"):
|
|
ImageFilter.Color3DLUT((11, 11, 1), [1])
|
|
|
|
with self.assertRaisesRegex(ValueError, r"in \[2, 65\] range"):
|
|
ImageFilter.Color3DLUT((11, 11, 66), [1])
|
|
|
|
with self.assertRaisesRegex(ValueError, "table should have .+ items"):
|
|
ImageFilter.Color3DLUT((3, 3, 3), [1, 1, 1])
|
|
|
|
with self.assertRaisesRegex(ValueError, "table should have .+ items"):
|
|
ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 2)
|
|
|
|
with self.assertRaisesRegex(ValueError, "should have a length of 4"):
|
|
ImageFilter.Color3DLUT((3, 3, 3), [[1, 1, 1]] * 27, channels=4)
|
|
|
|
with self.assertRaisesRegex(ValueError, "should have a length of 3"):
|
|
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8)
|
|
|
|
with self.assertRaisesRegex(ValueError, "Only 3 or 4 output"):
|
|
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8, channels=2)
|
|
|
|
def test_convert_table(self):
|
|
lut = ImageFilter.Color3DLUT(2, [0, 1, 2] * 8)
|
|
self.assertEqual(tuple(lut.size), (2, 2, 2))
|
|
self.assertEqual(lut.name, "Color 3D LUT")
|
|
|
|
lut = ImageFilter.Color3DLUT((2, 2, 2), [
|
|
(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11),
|
|
(12, 13, 14), (15, 16, 17), (18, 19, 20), (21, 22, 23)])
|
|
self.assertEqual(tuple(lut.size), (2, 2, 2))
|
|
self.assertEqual(lut.table, list(range(24)))
|
|
|
|
lut = ImageFilter.Color3DLUT((2, 2, 2), [(0, 1, 2, 3)] * 8,
|
|
channels=4)
|
|
self.assertEqual(tuple(lut.size), (2, 2, 2))
|
|
self.assertEqual(lut.table, list(range(4)) * 8)
|
|
|
|
@unittest.skipIf(numpy is None, "Numpy is not installed")
|
|
def test_numpy_sources(self):
|
|
table = numpy.ones((5, 6, 7, 3), dtype=numpy.float16)
|
|
with self.assertRaisesRegex(ValueError, "should have either channels"):
|
|
lut = ImageFilter.Color3DLUT((5, 6, 7), table)
|
|
|
|
table = numpy.ones((7, 6, 5, 3), dtype=numpy.float16)
|
|
lut = ImageFilter.Color3DLUT((5, 6, 7), table)
|
|
self.assertIsInstance(lut.table, numpy.ndarray)
|
|
self.assertEqual(lut.table.dtype, table.dtype)
|
|
self.assertEqual(lut.table.shape, (table.size,))
|
|
|
|
table = numpy.ones((7 * 6 * 5, 3), dtype=numpy.float16)
|
|
lut = ImageFilter.Color3DLUT((5, 6, 7), table)
|
|
self.assertEqual(lut.table.shape, (table.size,))
|
|
|
|
table = numpy.ones((7 * 6 * 5 * 3), dtype=numpy.float16)
|
|
lut = ImageFilter.Color3DLUT((5, 6, 7), table)
|
|
self.assertEqual(lut.table.shape, (table.size,))
|
|
|
|
# Check application
|
|
Image.new('RGB', (10, 10), 0).filter(lut)
|
|
|
|
# Check copy
|
|
table[0] = 33
|
|
self.assertEqual(lut.table[0], 1)
|
|
|
|
# Check not copy
|
|
table = numpy.ones((7 * 6 * 5 * 3), dtype=numpy.float16)
|
|
lut = ImageFilter.Color3DLUT((5, 6, 7), table, _copy_table=False)
|
|
table[0] = 33
|
|
self.assertEqual(lut.table[0], 33)
|
|
|
|
@unittest.skipIf(numpy is None, "Numpy is not installed")
|
|
def test_numpy_formats(self):
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180)])
|
|
|
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11),
|
|
lambda r, g, b: (r, g, b))
|
|
lut.table = numpy.array(lut.table, dtype=numpy.float32)[:-1]
|
|
with self.assertRaisesRegex(ValueError, "should have table_channels"):
|
|
im.filter(lut)
|
|
|
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11),
|
|
lambda r, g, b: (r, g, b))
|
|
lut.table = (numpy.array(lut.table, dtype=numpy.float32)
|
|
.reshape((7 * 9 * 11), 3))
|
|
with self.assertRaisesRegex(ValueError, "should have table_channels"):
|
|
im.filter(lut)
|
|
|
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11),
|
|
lambda r, g, b: (r, g, b))
|
|
lut.table = numpy.array(lut.table, dtype=numpy.float16)
|
|
self.assert_image_equal(im, im.filter(lut))
|
|
|
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11),
|
|
lambda r, g, b: (r, g, b))
|
|
lut.table = numpy.array(lut.table, dtype=numpy.float32)
|
|
self.assert_image_equal(im, im.filter(lut))
|
|
|
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11),
|
|
lambda r, g, b: (r, g, b))
|
|
lut.table = numpy.array(lut.table, dtype=numpy.float64)
|
|
self.assert_image_equal(im, im.filter(lut))
|
|
|
|
lut = ImageFilter.Color3DLUT.generate((7, 9, 11),
|
|
lambda r, g, b: (r, g, b))
|
|
lut.table = numpy.array(lut.table, dtype=numpy.int32)
|
|
im.filter(lut)
|
|
lut.table = numpy.array(lut.table, dtype=numpy.int8)
|
|
im.filter(lut)
|
|
|
|
def test_repr(self):
|
|
lut = ImageFilter.Color3DLUT(2, [0, 1, 2] * 8)
|
|
self.assertEqual(repr(lut),
|
|
"<Color3DLUT from list size=2x2x2 channels=3>")
|
|
|
|
lut = ImageFilter.Color3DLUT(
|
|
(3, 4, 5), array('f', [0, 0, 0, 0] * (3 * 4 * 5)),
|
|
channels=4, target_mode='YCbCr', _copy_table=False)
|
|
self.assertEqual(
|
|
repr(lut),
|
|
"<Color3DLUT from array size=3x4x5 channels=4 target_mode=YCbCr>")
|
|
|
|
|
|
class TestGenerateColorLut3D(PillowTestCase):
|
|
def test_wrong_channels_count(self):
|
|
with self.assertRaisesRegex(ValueError, "3 or 4 output channels"):
|
|
ImageFilter.Color3DLUT.generate(
|
|
5, channels=2, callback=lambda r, g, b: (r, g, b))
|
|
|
|
with self.assertRaisesRegex(ValueError, "should have either channels"):
|
|
ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b, r))
|
|
|
|
with self.assertRaisesRegex(ValueError, "should have either channels"):
|
|
ImageFilter.Color3DLUT.generate(
|
|
5, channels=4, callback=lambda r, g, b: (r, g, b))
|
|
|
|
def test_3_channels(self):
|
|
lut = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b))
|
|
self.assertEqual(tuple(lut.size), (5, 5, 5))
|
|
self.assertEqual(lut.name, "Color 3D LUT")
|
|
self.assertEqual(lut.table[:24], [
|
|
0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.5, 0.0, 0.0, 0.75, 0.0, 0.0,
|
|
1.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.25, 0.25, 0.0, 0.5, 0.25, 0.0])
|
|
|
|
def test_4_channels(self):
|
|
lut = ImageFilter.Color3DLUT.generate(
|
|
5, channels=4, callback=lambda r, g, b: (b, r, g, (r+g+b) / 2))
|
|
self.assertEqual(tuple(lut.size), (5, 5, 5))
|
|
self.assertEqual(lut.name, "Color 3D LUT")
|
|
self.assertEqual(lut.table[:24], [
|
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.125, 0.0, 0.5, 0.0, 0.25,
|
|
0.0, 0.75, 0.0, 0.375, 0.0, 1.0, 0.0, 0.5, 0.0, 0.0, 0.25, 0.125
|
|
])
|
|
|
|
def test_apply(self):
|
|
lut = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b))
|
|
|
|
g = Image.linear_gradient('L')
|
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
|
g.transpose(Image.ROTATE_180)])
|
|
self.assertEqual(im, im.filter(lut))
|
|
|
|
|
|
class TestTransformColorLut3D(PillowTestCase):
|
|
def test_wrong_args(self):
|
|
source = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b))
|
|
|
|
with self.assertRaisesRegex(ValueError, "Only 3 or 4 output"):
|
|
source.transform(lambda r, g, b: (r, g, b), channels=8)
|
|
|
|
with self.assertRaisesRegex(ValueError, "should have either channels"):
|
|
source.transform(lambda r, g, b: (r, g, b), channels=4)
|
|
|
|
with self.assertRaisesRegex(ValueError, "should have either channels"):
|
|
source.transform(lambda r, g, b: (r, g, b, 1))
|
|
|
|
with self.assertRaises(TypeError):
|
|
source.transform(lambda r, g, b, a: (r, g, b))
|
|
|
|
def test_target_mode(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
2, lambda r, g, b: (r, g, b), target_mode='HSV')
|
|
|
|
lut = source.transform(lambda r, g, b: (r, g, b))
|
|
self.assertEqual(lut.mode, 'HSV')
|
|
|
|
lut = source.transform(lambda r, g, b: (r, g, b), target_mode='RGB')
|
|
self.assertEqual(lut.mode, 'RGB')
|
|
|
|
def test_3_to_3_channels(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
(3, 4, 5), lambda r, g, b: (r, g, b))
|
|
lut = source.transform(lambda r, g, b: (r*r, g*g, b*b))
|
|
self.assertEqual(tuple(lut.size), tuple(source.size))
|
|
self.assertEqual(len(lut.table), len(source.table))
|
|
self.assertNotEqual(lut.table, source.table)
|
|
self.assertEqual(lut.table[0:10], [
|
|
0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0])
|
|
|
|
def test_3_to_4_channels(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
(6, 5, 4), lambda r, g, b: (r, g, b))
|
|
lut = source.transform(lambda r, g, b: (r*r, g*g, b*b, 1), channels=4)
|
|
self.assertEqual(tuple(lut.size), tuple(source.size))
|
|
self.assertNotEqual(len(lut.table), len(source.table))
|
|
self.assertNotEqual(lut.table, source.table)
|
|
self.assertEqual(lut.table[0:16], [
|
|
0.0, 0.0, 0.0, 1, 0.2**2, 0.0, 0.0, 1,
|
|
0.4**2, 0.0, 0.0, 1, 0.6**2, 0.0, 0.0, 1])
|
|
|
|
def test_4_to_3_channels(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
(3, 6, 5), lambda r, g, b: (r, g, b, 1), channels=4)
|
|
lut = source.transform(lambda r, g, b, a: (a - r*r, a - g*g, a - b*b),
|
|
channels=3)
|
|
self.assertEqual(tuple(lut.size), tuple(source.size))
|
|
self.assertNotEqual(len(lut.table), len(source.table))
|
|
self.assertNotEqual(lut.table, source.table)
|
|
self.assertEqual(lut.table[0:18], [
|
|
1.0, 1.0, 1.0, 0.75, 1.0, 1.0, 0.0, 1.0, 1.0,
|
|
1.0, 0.96, 1.0, 0.75, 0.96, 1.0, 0.0, 0.96, 1.0])
|
|
|
|
def test_4_to_4_channels(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
(6, 5, 4), lambda r, g, b: (r, g, b, 1), channels=4)
|
|
lut = source.transform(lambda r, g, b, a: (r*r, g*g, b*b, a - 0.5))
|
|
self.assertEqual(tuple(lut.size), tuple(source.size))
|
|
self.assertEqual(len(lut.table), len(source.table))
|
|
self.assertNotEqual(lut.table, source.table)
|
|
self.assertEqual(lut.table[0:16], [
|
|
0.0, 0.0, 0.0, 0.5, 0.2**2, 0.0, 0.0, 0.5,
|
|
0.4**2, 0.0, 0.0, 0.5, 0.6**2, 0.0, 0.0, 0.5])
|
|
|
|
def test_with_normals_3_channels(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
(6, 5, 4), lambda r, g, b: (r*r, g*g, b*b))
|
|
lut = source.transform(
|
|
lambda nr, ng, nb, r, g, b: (nr - r, ng - g, nb - b),
|
|
with_normals=True)
|
|
self.assertEqual(tuple(lut.size), tuple(source.size))
|
|
self.assertEqual(len(lut.table), len(source.table))
|
|
self.assertNotEqual(lut.table, source.table)
|
|
self.assertEqual(lut.table[0:18], [
|
|
0.0, 0.0, 0.0, 0.16, 0.0, 0.0, 0.24, 0.0, 0.0,
|
|
0.24, 0.0, 0.0, 0.8 - (0.8**2), 0, 0, 0, 0, 0])
|
|
|
|
def test_with_normals_4_channels(self):
|
|
source = ImageFilter.Color3DLUT.generate(
|
|
(3, 6, 5), lambda r, g, b: (r*r, g*g, b*b, 1), channels=4)
|
|
lut = source.transform(
|
|
lambda nr, ng, nb, r, g, b, a: (nr - r, ng - g, nb - b, a-0.5),
|
|
with_normals=True)
|
|
self.assertEqual(tuple(lut.size), tuple(source.size))
|
|
self.assertEqual(len(lut.table), len(source.table))
|
|
self.assertNotEqual(lut.table, source.table)
|
|
self.assertEqual(lut.table[0:16], [
|
|
0.0, 0.0, 0.0, 0.5, 0.25, 0.0, 0.0, 0.5,
|
|
0.0, 0.0, 0.0, 0.5, 0.0, 0.16, 0.0, 0.5])
|