Merge pull request #441 from wiredfool/lut

Image.point fixes for numpy.array and docs
This commit is contained in:
Alex Clark ☺ 2013-12-28 06:08:08 -08:00
commit ae7edfa58d
3 changed files with 32 additions and 7 deletions

View File

@ -1128,14 +1128,16 @@ class Image:
""" """
Maps this image through a lookup table or function. Maps this image through a lookup table or function.
:param lut: A lookup table, containing 256 values per band in the :param lut: A lookup table, containing 256 (or 65336 if
image. A function can be used instead, it should take a single self.mode=="I" and mode == "L") values per band in the
argument. The function is called once for each possible pixel image. A function can be used instead, it should take a
value, and the resulting table is applied to all bands of the single argument. The function is called once for each
image. possible pixel value, and the resulting table is applied to
all bands of the image.
:param mode: Output mode (default is same as input). In the :param mode: Output mode (default is same as input). In the
current version, this can only be used if the source image current version, this can only be used if the source image
has mode "L" or "P", and the output has mode "1". has mode "L" or "P", and the output has mode "1" or the
source image mode is "I" and the output mode is "L".
:returns: An :py:class:`~PIL.Image.Image` object. :returns: An :py:class:`~PIL.Image.Image` object.
""" """
@ -1144,10 +1146,12 @@ class Image:
if isinstance(lut, ImagePointHandler): if isinstance(lut, ImagePointHandler):
return lut.point(self) return lut.point(self)
if not isinstance(lut, collections.Sequence): if callable(lut):
# if it isn't a list, it should be a function # if it isn't a list, it should be a function
if self.mode in ("I", "I;16", "F"): if self.mode in ("I", "I;16", "F"):
# check if the function can be used with point_transform # check if the function can be used with point_transform
# UNDONE wiredfool -- I think this prevents us from ever doing
# a gamma function point transform on > 8bit images.
scale, offset = _getscaleoffset(lut) scale, offset = _getscaleoffset(lut)
return self._new(self.im.point_transform(scale, offset)) return self._new(self.im.point_transform(scale, offset))
# for other modes, convert the function to a table # for other modes, convert the function to a table

View File

@ -17,3 +17,12 @@ def test_sanity():
assert_no_exception(lambda: im.point(lambda x: x*1+1)) assert_no_exception(lambda: im.point(lambda x: x*1+1))
assert_exception(TypeError, lambda: im.point(lambda x: x-1)) assert_exception(TypeError, lambda: im.point(lambda x: x-1))
assert_exception(TypeError, lambda: im.point(lambda x: x/1)) assert_exception(TypeError, lambda: im.point(lambda x: x/1))
def test_16bit_lut():
""" Tests for 16 bit -> 8 bit lut for converting I->L images
see https://github.com/python-imaging/Pillow/issues/440
"""
im = lena("I")
assert_no_exception(lambda: im.point(list(range(256))*256, 'L'))

View File

@ -106,3 +106,15 @@ def test_to_array():
for mode in modes: for mode in modes:
assert_no_exception(lambda: _to_array(*mode)) assert_no_exception(lambda: _to_array(*mode))
def test_point_lut():
# see https://github.com/python-imaging/Pillow/issues/439
data = list(range(256))*3
lut = numpy.array(data, dtype='uint8')
im = lena()
assert_no_exception(lambda: im.point(lut))