Merge branch 'dschmidt_palette_513' of https://github.com/wiredfool/Pillow into wiredfool-dschmidt_palette_513

This commit is contained in:
Alex Clark 2014-03-17 09:48:24 -04:00
commit 0e9f4c6c60
7 changed files with 65 additions and 9 deletions

View File

@ -13,6 +13,9 @@ Changelog (Pillow)
- Fixed opening and saving odd sized .pcx files, fixes #523
[wiredfool]
- Fixed palette handling when converting from mode P->RGB->P
[d_schmidt]
- Fixed saving mode P image as a PNG with transparency = palette color 0
[d-schmidt]

View File

@ -237,7 +237,10 @@ def _save(im, fp, filename):
# convert on the fly (EXPERIMENTAL -- I'm not sure PIL
# should automatically convert images on save...)
if Image.getmodebase(im.mode) == "RGB":
imOut = im.convert("P")
palette_size = 256
if im.palette:
palette_size = len(im.palette.getdata()[1]) // 3
imOut = im.convert("P", palette=1, colors=palette_size)
rawmode = "P"
else:
imOut = im.convert("L")
@ -248,9 +251,13 @@ def _save(im, fp, filename):
palette = im.encoderinfo["palette"]
except KeyError:
palette = None
if im.palette:
# use existing if possible
palette = im.palette.getdata()[1]
im.encoderinfo["optimize"] = im.encoderinfo.get("optimize", True)
if im.encoderinfo["optimize"]:
# When the mode is L, and we optimize, we end up with
# im.mode == P and rawmode = L, which fails.
# If we're optimizing the palette, we're going to be
# in a rawmode of P anyway.
rawmode = 'P'
header, usedPaletteColors = getheader(imOut, palette, im.encoderinfo)
for s in header:
@ -391,6 +398,9 @@ def getheader(im, palette=None, info=None):
for i in range(len(imageBytes)):
imageBytes[i] = newPositions[imageBytes[i]]
im.frombytes(bytes(imageBytes))
newPaletteBytes = paletteBytes + (768 - len(paletteBytes)) * b'\x00'
im.putpalette(newPaletteBytes)
im.palette = ImagePalette.ImagePalette("RGB", palette = paletteBytes, size = len(paletteBytes))
if not paletteBytes:
paletteBytes = sourcePalette

View File

@ -737,7 +737,10 @@ class Image:
if mode == "P" and palette == ADAPTIVE:
im = self.im.quantize(colors)
return self._new(im)
new = self._new(im)
from PIL import ImagePalette
new.palette = ImagePalette.raw("RGB", new.im.getpalette("RGB"))
return new
# colorspace conversion
if dither is None:

View File

@ -23,13 +23,14 @@ from PIL import Image, ImageColor
class ImagePalette:
"Color palette for palette mapped images"
def __init__(self, mode = "RGB", palette = None):
def __init__(self, mode = "RGB", palette = None, size = 0):
self.mode = mode
self.rawmode = None # if set, palette contains raw data
self.palette = palette or list(range(256))*len(self.mode)
self.colors = {}
self.dirty = None
if len(self.mode)*256 != len(self.palette):
if ((size == 0 and len(self.mode)*256 != len(self.palette)) or
(size != 0 and size != len(self.palette))):
raise ValueError("wrong palette size")
def getdata(self):

View File

@ -505,7 +505,7 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
else:
# check palette contents
if im.palette:
colors = len(im.palette.getdata()[1])//3
colors = max(min(len(im.palette.getdata()[1])//3, 256), 2)
else:
colors = 256

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -38,7 +38,7 @@ def test_roundtrip():
def test_roundtrip2():
#see https://github.com/python-imaging/Pillow/issues/403
out = 'temp.gif'#tempfile('temp.gif')
out = tempfile('temp.gif')
im = Image.open('Images/lena.gif')
im2 = im.copy()
im2.save(out)
@ -46,3 +46,42 @@ def test_roundtrip2():
assert_image_similar(reread.convert('RGB'), lena(), 50)
def test_palette_handling():
# see https://github.com/python-imaging/Pillow/issues/513
im = Image.open('Images/lena.gif')
im = im.convert('RGB')
im = im.resize((100,100), Image.ANTIALIAS)
im2 = im.convert('P', palette=Image.ADAPTIVE, colors=256)
f = tempfile('temp.gif')
im2.save(f, optimize=True)
reloaded = Image.open(f)
assert_image_similar(im, reloaded.convert('RGB'), 10)
def test_palette_434():
# see https://github.com/python-imaging/Pillow/issues/434
def roundtrip(im, *args, **kwargs):
out = tempfile('temp.gif')
im.save(out, *args, **kwargs)
reloaded = Image.open(out)
return [im, reloaded]
orig = "Tests/images/test.colors.gif"
im = Image.open(orig)
assert_image_equal(*roundtrip(im))
assert_image_equal(*roundtrip(im, optimize=True))
im = im.convert("RGB")
# check automatic P conversion
reloaded = roundtrip(im)[1].convert('RGB')
assert_image_equal(im, reloaded)