Keep subsequent L frames without transparency as L

This commit is contained in:
Andrew Murray 2022-03-20 15:09:01 +11:00
parent a6a843e548
commit 7928e944cb
4 changed files with 30 additions and 17 deletions

BIN
Tests/images/no_palette.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 B

View File

@ -59,7 +59,15 @@ def test_invalid_file():
GifImagePlugin.GifImageFile(invalid_file)
def test_l_mode_transparency():
def test_l_mode_subsequent_frames():
with Image.open("Tests/images/no_palette.gif") as im:
assert im.mode == "L"
assert im.load()[0, 0] == 0
im.seek(1)
assert im.mode == "L"
assert im.load()[0, 0] == 0
with Image.open("Tests/images/no_palette_with_transparency.gif") as im:
assert im.mode == "L"
assert im.load()[0, 0] == 0

View File

@ -106,8 +106,9 @@ writes run-length encoded files in GIF87a by default, unless GIF89a features
are used or GIF89a is already in use.
GIF files are initially read as grayscale (``L``) or palette mode (``P``)
images, but seeking to later frames in an image will change the mode to either
``RGB`` or ``RGBA``, depending on whether the first frame had transparency.
images. Seeking to later frames in a ``P`` image will change the image to
``RGB`` (or ``RGBA`` if the first frame had transparency). ``L`` images will
stay in ``L`` mode (or change to ``LA`` if the first frame had transparency).
The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

View File

@ -174,21 +174,22 @@ class GifImageFile(ImageFile.ImageFile):
if update_image:
if self.__frame == 1:
self.pyaccess = None
if "transparency" in self.info:
if self.mode == "P":
if self.mode == "P":
if "transparency" in self.info:
self.im.putpalettealpha(self.info["transparency"], 0)
self.im = self.im.convert("RGBA", Image.Dither.FLOYDSTEINBERG)
self.mode = "RGBA"
del self.info["transparency"]
else:
self.im = self.im.convert_transparent(
"LA", self.info["transparency"]
)
self.mode = "LA"
self.mode = "RGB"
self.im = self.im.convert("RGB", Image.Dither.FLOYDSTEINBERG)
elif "transparency" in self.info:
self.im = self.im.convert_transparent(
"LA", self.info["transparency"]
)
self.mode = "LA"
del self.info["transparency"]
else:
self.mode = "RGB"
self.im = self.im.convert("RGB", Image.Dither.FLOYDSTEINBERG)
if self.dispose:
self.im.paste(self.dispose, self.dispose_extent)
@ -387,14 +388,17 @@ class GifImageFile(ImageFile.ImageFile):
def load_end(self):
if self.__frame == 0:
return
if self._frame_transparency is not None:
if self.mode == "P":
if self.mode == "P":
if self._frame_transparency is not None:
self.im.putpalettealpha(self._frame_transparency, 0)
frame_im = self.im.convert("RGBA")
else:
frame_im = self.im.convert_transparent("LA", self._frame_transparency)
frame_im = self.im.convert("RGB")
else:
frame_im = self.im.convert("RGB")
if self._frame_transparency is not None:
frame_im = self.im.convert_transparent("LA", self._frame_transparency)
else:
frame_im = self.im
frame_im = self._crop(frame_im, self.dispose_extent)
self.im = self._prev_im