mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 10:46:16 +03:00
Merge pull request #665 from hugovk/transparency
Remove transparency resource after converting P->RGBA, Fixes #664
This commit is contained in:
commit
fb164d0a6e
39
PIL/Image.py
39
PIL/Image.py
|
@ -101,7 +101,7 @@ import collections
|
|||
import numbers
|
||||
|
||||
# works everywhere, win for pypy, not cpython
|
||||
USE_CFFI_ACCESS = hasattr(sys, 'pypy_version_info')
|
||||
USE_CFFI_ACCESS = hasattr(sys, 'pypy_version_info')
|
||||
try:
|
||||
import cffi
|
||||
HAS_CFFI=True
|
||||
|
@ -233,7 +233,7 @@ _MODE_CONV = {
|
|||
"CMYK": ('|u1', 4),
|
||||
"YCbCr": ('|u1', 3),
|
||||
"LAB": ('|u1', 3), # UNDONE - unsigned |u1i1i1
|
||||
# I;16 == I;16L, and I;32 == I;32L
|
||||
# I;16 == I;16L, and I;32 == I;32L
|
||||
"I;16": ('<u2', None),
|
||||
"I;16B": ('>u2', None),
|
||||
"I;16L": ('<u2', None),
|
||||
|
@ -502,7 +502,7 @@ class Image:
|
|||
return self
|
||||
def __exit__(self, *args):
|
||||
self.close()
|
||||
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Closes the file pointer, if possible.
|
||||
|
@ -524,7 +524,7 @@ class Image:
|
|||
# deferred error that will better explain that the core image
|
||||
# object is gone.
|
||||
self.im = deferred_error(ValueError("Operation on closed image"))
|
||||
|
||||
|
||||
|
||||
def _copy(self):
|
||||
self.load()
|
||||
|
@ -540,7 +540,7 @@ class Image:
|
|||
if not file:
|
||||
f, file = tempfile.mkstemp(suffix)
|
||||
os.close(f)
|
||||
|
||||
|
||||
self.load()
|
||||
if not format or format == "PPM":
|
||||
self.im.save_ppm(file)
|
||||
|
@ -672,7 +672,7 @@ class Image:
|
|||
normal cases, you don't need to call this method, since the
|
||||
Image class automatically loads an opened image when it is
|
||||
accessed for the first time. This method will close the file
|
||||
associated with the image.
|
||||
associated with the image.
|
||||
|
||||
:returns: An image access object.
|
||||
"""
|
||||
|
@ -777,7 +777,7 @@ class Image:
|
|||
if "transparency" in self.info and self.info['transparency'] is not None:
|
||||
if self.mode in ('L', 'RGB') and mode == 'RGBA':
|
||||
# Use transparent conversion to promote from transparent
|
||||
# color to an alpha channel.
|
||||
# color to an alpha channel.
|
||||
return self._new(self.im.convert_transparent(
|
||||
mode, self.info['transparency']))
|
||||
elif self.mode in ('L', 'RGB', 'P') and mode in ('L', 'RGB', 'P'):
|
||||
|
@ -799,11 +799,12 @@ class Image:
|
|||
trns_im = trns_im.convert(mode)
|
||||
else:
|
||||
# can't just retrieve the palette number, got to do it
|
||||
# after quantization.
|
||||
# after quantization.
|
||||
trns_im = trns_im.convert('RGB')
|
||||
trns = trns_im.getpixel((0,0))
|
||||
|
||||
|
||||
elif self.mode == 'P' and mode == 'RGBA':
|
||||
delete_trns = True
|
||||
|
||||
if mode == "P" and palette == ADAPTIVE:
|
||||
im = self.im.quantize(colors)
|
||||
new = self._new(im)
|
||||
|
@ -811,7 +812,7 @@ class Image:
|
|||
new.palette = ImagePalette.raw("RGB", new.im.getpalette("RGB"))
|
||||
if delete_trns:
|
||||
# This could possibly happen if we requantize to fewer colors.
|
||||
# The transparency would be totally off in that case.
|
||||
# The transparency would be totally off in that case.
|
||||
del(new.info['transparency'])
|
||||
if trns is not None:
|
||||
try:
|
||||
|
@ -826,7 +827,7 @@ class Image:
|
|||
# colorspace conversion
|
||||
if dither is None:
|
||||
dither = FLOYDSTEINBERG
|
||||
|
||||
|
||||
try:
|
||||
im = self.im.convert(mode, dither)
|
||||
except ValueError:
|
||||
|
@ -863,7 +864,7 @@ class Image:
|
|||
# quantizer interface in a later version of PIL.
|
||||
|
||||
self.load()
|
||||
|
||||
|
||||
if method is None:
|
||||
# defaults:
|
||||
method = 0
|
||||
|
@ -871,10 +872,10 @@ class Image:
|
|||
method = 2
|
||||
|
||||
if self.mode == 'RGBA' and method != 2:
|
||||
# Caller specified an invalid mode.
|
||||
# Caller specified an invalid mode.
|
||||
raise ValueError('Fast Octree (method == 2) is the ' +
|
||||
' only valid method for quantizing RGBA images')
|
||||
|
||||
|
||||
if palette:
|
||||
# use palette from reference image
|
||||
palette.load()
|
||||
|
@ -928,7 +929,7 @@ class Image:
|
|||
def draft(self, mode, size):
|
||||
"""
|
||||
NYI
|
||||
|
||||
|
||||
Configures the image file loader so it returns a version of the
|
||||
image that as closely as possible matches the given mode and
|
||||
size. For example, you can use this method to convert a color
|
||||
|
@ -1277,7 +1278,7 @@ class Image:
|
|||
if self.mode in ("I", "I;16", "F"):
|
||||
# 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.
|
||||
# a gamma function point transform on > 8bit images.
|
||||
scale, offset = _getscaleoffset(lut)
|
||||
return self._new(self.im.point_transform(scale, offset))
|
||||
# for other modes, convert the function to a table
|
||||
|
@ -1420,8 +1421,8 @@ class Image:
|
|||
self._copy()
|
||||
self.pyaccess = None
|
||||
self.load()
|
||||
|
||||
if self.pyaccess:
|
||||
|
||||
if self.pyaccess:
|
||||
return self.pyaccess.putpixel(xy,value)
|
||||
return self.im.putpixel(xy, value)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ from tester import *
|
|||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def test_sanity():
|
||||
|
||||
def convert(im, mode):
|
||||
|
@ -16,6 +17,7 @@ def test_sanity():
|
|||
for mode in modes:
|
||||
yield_test(convert, im, mode)
|
||||
|
||||
|
||||
def test_default():
|
||||
|
||||
im = lena("P")
|
||||
|
@ -26,26 +28,29 @@ def test_default():
|
|||
assert_image(im, "RGB", im.size)
|
||||
|
||||
|
||||
|
||||
# ref https://github.com/python-imaging/Pillow/issues/274
|
||||
|
||||
def _test_float_conversion(im):
|
||||
orig = im.getpixel((5,5))
|
||||
converted = im.convert('F').getpixel((5,5))
|
||||
orig = im.getpixel((5, 5))
|
||||
converted = im.convert('F').getpixel((5, 5))
|
||||
assert_equal(orig, converted)
|
||||
|
||||
|
||||
def test_8bit():
|
||||
im = Image.open('Images/lena.jpg')
|
||||
_test_float_conversion(im.convert('L'))
|
||||
|
||||
|
||||
def test_16bit():
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
_test_float_conversion(im)
|
||||
|
||||
|
||||
def test_16bit_workaround():
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
_test_float_conversion(im.convert('I'))
|
||||
|
||||
|
||||
|
||||
def test_rgba_p():
|
||||
im = lena('RGBA')
|
||||
im.putalpha(lena('L'))
|
||||
|
@ -54,30 +59,45 @@ def test_rgba_p():
|
|||
comparable = converted.convert('RGBA')
|
||||
|
||||
assert_image_similar(im, comparable, 20)
|
||||
|
||||
def test_trns_p():
|
||||
|
||||
|
||||
def test_trns_p():
|
||||
im = lena('P')
|
||||
im.info['transparency']=0
|
||||
im.info['transparency'] = 0
|
||||
|
||||
f = tempfile('temp.png')
|
||||
|
||||
l = im.convert('L')
|
||||
assert_equal(l.info['transparency'], 0) # undone
|
||||
assert_equal(l.info['transparency'], 0) # undone
|
||||
assert_no_exception(lambda: l.save(f))
|
||||
|
||||
|
||||
rgb = im.convert('RGB')
|
||||
assert_equal(rgb.info['transparency'], (0,0,0)) # undone
|
||||
assert_equal(rgb.info['transparency'], (0, 0, 0)) # undone
|
||||
assert_no_exception(lambda: rgb.save(f))
|
||||
|
||||
|
||||
|
||||
# ref https://github.com/python-imaging/Pillow/issues/664
|
||||
|
||||
def test_trns_p_rgba():
|
||||
# Arrange
|
||||
im = lena('P')
|
||||
im.info['transparency'] = 128
|
||||
|
||||
# Act
|
||||
rgba = im.convert('RGBA')
|
||||
|
||||
# Assert
|
||||
assert_false('transparency' in rgba.info)
|
||||
|
||||
|
||||
def test_trns_l():
|
||||
im = lena('L')
|
||||
im.info['transparency'] = 128
|
||||
|
||||
f = tempfile('temp.png')
|
||||
|
||||
|
||||
rgb = im.convert('RGB')
|
||||
assert_equal(rgb.info['transparency'], (128,128,128)) # undone
|
||||
assert_equal(rgb.info['transparency'], (128, 128, 128)) # undone
|
||||
assert_no_exception(lambda: rgb.save(f))
|
||||
|
||||
p = im.convert('P')
|
||||
|
@ -85,28 +105,26 @@ def test_trns_l():
|
|||
assert_no_exception(lambda: p.save(f))
|
||||
|
||||
p = assert_warning(UserWarning,
|
||||
lambda: im.convert('P', palette = Image.ADAPTIVE))
|
||||
lambda: im.convert('P', palette=Image.ADAPTIVE))
|
||||
assert_false('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
|
||||
|
||||
|
||||
def test_trns_RGB():
|
||||
im = lena('RGB')
|
||||
im.info['transparency'] = im.getpixel((0,0))
|
||||
im.info['transparency'] = im.getpixel((0, 0))
|
||||
|
||||
f = tempfile('temp.png')
|
||||
|
||||
|
||||
l = im.convert('L')
|
||||
assert_equal(l.info['transparency'], l.getpixel((0,0))) # undone
|
||||
assert_equal(l.info['transparency'], l.getpixel((0, 0))) # undone
|
||||
assert_no_exception(lambda: l.save(f))
|
||||
|
||||
p = im.convert('P')
|
||||
assert_true('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
|
||||
|
||||
p = assert_warning(UserWarning,
|
||||
lambda: im.convert('P', palette = Image.ADAPTIVE))
|
||||
lambda: im.convert('P', palette=Image.ADAPTIVE))
|
||||
assert_false('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user