mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-05 06:00:58 +03:00
from_cube_file + test
This commit is contained in:
parent
d2a5d1e44d
commit
aa929dda98
|
@ -253,37 +253,37 @@ class TestColorLut3DFilter(PillowTestCase):
|
||||||
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8)
|
ImageFilter.Color3DLUT((2, 2, 2), [[1, 1]] * 8)
|
||||||
|
|
||||||
def test_convert_table(self):
|
def test_convert_table(self):
|
||||||
flt = ImageFilter.Color3DLUT(2, [0, 1, 2] * 8)
|
lut = ImageFilter.Color3DLUT(2, [0, 1, 2] * 8)
|
||||||
self.assertEqual(tuple(flt.size), (2, 2, 2))
|
self.assertEqual(tuple(lut.size), (2, 2, 2))
|
||||||
self.assertEqual(flt.name, "Color 3D LUT")
|
self.assertEqual(lut.name, "Color 3D LUT")
|
||||||
|
|
||||||
flt = ImageFilter.Color3DLUT((2, 2, 2), [
|
lut = ImageFilter.Color3DLUT((2, 2, 2), [
|
||||||
(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11),
|
(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11),
|
||||||
(12, 13, 14), (15, 16, 17), (18, 19, 20), (21, 22, 23)])
|
(12, 13, 14), (15, 16, 17), (18, 19, 20), (21, 22, 23)])
|
||||||
self.assertEqual(tuple(flt.size), (2, 2, 2))
|
self.assertEqual(tuple(lut.size), (2, 2, 2))
|
||||||
self.assertEqual(flt.table, list(range(24)))
|
self.assertEqual(lut.table, list(range(24)))
|
||||||
|
|
||||||
flt = ImageFilter.Color3DLUT((2, 2, 2), [(0, 1, 2, 3)] * 8,
|
lut = ImageFilter.Color3DLUT((2, 2, 2), [(0, 1, 2, 3)] * 8,
|
||||||
channels=4)
|
channels=4)
|
||||||
|
|
||||||
def test_generate(self):
|
def test_generate(self):
|
||||||
flt = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b))
|
lut = ImageFilter.Color3DLUT.generate(5, lambda r, g, b: (r, g, b))
|
||||||
self.assertEqual(tuple(flt.size), (5, 5, 5))
|
self.assertEqual(tuple(lut.size), (5, 5, 5))
|
||||||
self.assertEqual(flt.name, "Color 3D LUT")
|
self.assertEqual(lut.name, "Color 3D LUT")
|
||||||
self.assertEqual(flt.table[:24], [
|
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,
|
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])
|
1.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.25, 0.25, 0.0, 0.5, 0.25, 0.0])
|
||||||
|
|
||||||
g = Image.linear_gradient('L')
|
g = Image.linear_gradient('L')
|
||||||
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
im = Image.merge('RGB', [g, g.transpose(Image.ROTATE_90),
|
||||||
g.transpose(Image.ROTATE_180)])
|
g.transpose(Image.ROTATE_180)])
|
||||||
self.assertEqual(im, im.filter(flt))
|
self.assertEqual(im, im.filter(lut))
|
||||||
|
|
||||||
flt = ImageFilter.Color3DLUT.generate(5, channels=4,
|
lut = ImageFilter.Color3DLUT.generate(5, channels=4,
|
||||||
callback=lambda r, g, b: (b, r, g, (r+g+b) / 2))
|
callback=lambda r, g, b: (b, r, g, (r+g+b) / 2))
|
||||||
self.assertEqual(tuple(flt.size), (5, 5, 5))
|
self.assertEqual(tuple(lut.size), (5, 5, 5))
|
||||||
self.assertEqual(flt.name, "Color 3D LUT")
|
self.assertEqual(lut.name, "Color 3D LUT")
|
||||||
self.assertEqual(flt.table[:24], [
|
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.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])
|
0.0, 0.75, 0.0, 0.375, 0.0, 1.0, 0.0, 0.5, 0.0, 0.0, 0.25, 0.125])
|
||||||
|
|
||||||
|
@ -294,6 +294,47 @@ class TestColorLut3DFilter(PillowTestCase):
|
||||||
ImageFilter.Color3DLUT.generate(5, channels=4,
|
ImageFilter.Color3DLUT.generate(5, channels=4,
|
||||||
callback=lambda r, g, b: (r, g, b))
|
callback=lambda r, g, b: (r, g, b))
|
||||||
|
|
||||||
|
def test_from_cube_file_minimal(self):
|
||||||
|
lut = ImageFilter.Color3DLUT.from_cube_file([
|
||||||
|
"LUT_3D_SIZE 2",
|
||||||
|
"",
|
||||||
|
"0 0 0.031",
|
||||||
|
"0.96 0 0.031",
|
||||||
|
"0 1 0.031",
|
||||||
|
"0.96 1 0.031",
|
||||||
|
"0 0 0.931",
|
||||||
|
"0.96 0 0.931",
|
||||||
|
"0 1 0.931",
|
||||||
|
"0.96 1 0.931",
|
||||||
|
])
|
||||||
|
self.assertEqual(tuple(lut.size), (2, 2, 2))
|
||||||
|
self.assertEqual(lut.name, "Color 3D LUT")
|
||||||
|
self.assertEqual(lut.table[:12], [
|
||||||
|
0, 0, 0.031, 0.96, 0, 0.031, 0, 1, 0.031, 0.96, 1, 0.031])
|
||||||
|
|
||||||
|
def test_from_cube_file_parser(self):
|
||||||
|
lut = ImageFilter.Color3DLUT.from_cube_file([
|
||||||
|
" # Comment",
|
||||||
|
'TITLE "LUT name from file"',
|
||||||
|
"LUT_3D_SIZE 2 3 4",
|
||||||
|
" # Comment",
|
||||||
|
"CHANNELS 4",
|
||||||
|
"",
|
||||||
|
] + [
|
||||||
|
" # Comment",
|
||||||
|
"0 0 0.031 1",
|
||||||
|
"0.96 0 0.031 1",
|
||||||
|
"",
|
||||||
|
"0 1 0.031 1",
|
||||||
|
"0.96 1 0.031 1",
|
||||||
|
] * 6, target_mode='HSV')
|
||||||
|
self.assertEqual(tuple(lut.size), (2, 3, 4))
|
||||||
|
self.assertEqual(lut.channels, 4)
|
||||||
|
self.assertEqual(lut.name, "LUT name from file")
|
||||||
|
self.assertEqual(lut.mode, 'HSV')
|
||||||
|
self.assertEqual(lut.table[:12], [
|
||||||
|
0, 0, 0.031, 1, 0.96, 0, 0.031, 1, 0, 1, 0.031, 1])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
from ._util import isPath
|
||||||
|
|
||||||
|
|
||||||
class Filter(object):
|
class Filter(object):
|
||||||
pass
|
pass
|
||||||
|
@ -343,7 +345,8 @@ class Color3DLUT(MultibandFilter):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"The table should have channels * size**3 float items "
|
"The table should have channels * size**3 float items "
|
||||||
"either size**3 items of channels-sized tuples with floats. "
|
"either size**3 items of channels-sized tuples with floats. "
|
||||||
"Table length: {}".format(len(table)))
|
"Table size: {}x{}x{}. Table length: {}".format(
|
||||||
|
size[0], size[1], size[2], len(table)))
|
||||||
self.table = table
|
self.table = table
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -385,6 +388,58 @@ class Color3DLUT(MultibandFilter):
|
||||||
|
|
||||||
return cls((size1D, size2D, size3D), table, channels, target_mode)
|
return cls((size1D, size2D, size3D), table, channels, target_mode)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_cube_file(cls, lines, target_mode=None):
|
||||||
|
name, size = None, None
|
||||||
|
channels = 3
|
||||||
|
file = None
|
||||||
|
|
||||||
|
if isPath(lines):
|
||||||
|
file = lines = open(lines, 'rt')
|
||||||
|
|
||||||
|
try:
|
||||||
|
iterator = iter(lines)
|
||||||
|
|
||||||
|
for i, line in enumerate(iterator, 1):
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
if line.startswith('TITLE "'):
|
||||||
|
name = line.split('"')[1]
|
||||||
|
continue
|
||||||
|
if line.startswith('LUT_3D_SIZE '):
|
||||||
|
size = [int(x) for x in line.split()[1:]]
|
||||||
|
if len(size) == 1:
|
||||||
|
size = size[0]
|
||||||
|
continue
|
||||||
|
if line.startswith('CHANNELS '):
|
||||||
|
channels = int(line.split()[1])
|
||||||
|
|
||||||
|
if size is None:
|
||||||
|
raise ValueError('No size found in the file')
|
||||||
|
|
||||||
|
table = []
|
||||||
|
for i, line in enumerate(iterator, i + 1):
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith('#'):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
pixel = [float(x) for x in line.split()]
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError("Not a number on line {}".format(i))
|
||||||
|
if len(pixel) != channels:
|
||||||
|
raise ValueError(
|
||||||
|
"Wrong number of colors on line {}".format(i))
|
||||||
|
table.append(tuple(pixel))
|
||||||
|
finally:
|
||||||
|
if file is not None:
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
instance = cls(size, table, channels, target_mode)
|
||||||
|
if name is not None:
|
||||||
|
instance.name = name
|
||||||
|
return instance
|
||||||
|
|
||||||
def filter(self, image):
|
def filter(self, image):
|
||||||
from . import Image
|
from . import Image
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user