mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-28 19:06:18 +03:00
7da17ad41e
The previous test configuration made it difficult to run a single test with the pytest CLI. There were two major issues: - The Tests directory was not a package. It now includes a __init__.py file and imports from other tests modules are done with relative imports. - setup.cfg always specified the Tests directory. So even if a specific test were specified as a CLI arg, this configuration would also always include all tests. This configuration has been removed to allow specifying a single test on the command line. Contributors can now run specific tests with a single command such as: $ tox -e py37 -- Tests/test_file_pdf.py::TestFilePdf.test_rgb This makes it easy and faster to iterate on a single test failure and is very familiar to those that have previously used tox and pytest. When running tox or pytest with no arguments, they still discover and runs all tests in the Tests directory.
526 lines
22 KiB
Python
526 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])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|