mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-10 19:56:47 +03:00
When saving multiple frames, convert to mode rather than raw mode
This commit is contained in:
parent
bbe1effd63
commit
f34360d1e3
|
@ -655,11 +655,12 @@ class TestFilePng:
|
||||||
png.call(cid, 0, 0)
|
png.call(cid, 0, 0)
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
||||||
|
|
||||||
def test_specify_bits(self, tmp_path: Path) -> None:
|
@pytest.mark.parametrize("save_all", (True, False))
|
||||||
|
def test_specify_bits(self, save_all: bool, tmp_path: Path) -> None:
|
||||||
im = hopper("P")
|
im = hopper("P")
|
||||||
|
|
||||||
out = str(tmp_path / "temp.png")
|
out = str(tmp_path / "temp.png")
|
||||||
im.save(out, bits=4)
|
im.save(out, bits=4, save_all=save_all)
|
||||||
|
|
||||||
with Image.open(out) as reloaded:
|
with Image.open(out) as reloaded:
|
||||||
assert len(reloaded.png.im_palette[1]) == 48
|
assert len(reloaded.png.im_palette[1]) == 48
|
||||||
|
|
|
@ -1104,7 +1104,7 @@ class _fdat:
|
||||||
self.seq_num += 1
|
self.seq_num += 1
|
||||||
|
|
||||||
|
|
||||||
def _write_multiple_frames(im, fp, chunk, rawmode, default_image, append_images):
|
def _write_multiple_frames(im, fp, chunk, mode, rawmode, default_image, append_images):
|
||||||
duration = im.encoderinfo.get("duration", im.info.get("duration", 0))
|
duration = im.encoderinfo.get("duration", im.info.get("duration", 0))
|
||||||
loop = im.encoderinfo.get("loop", im.info.get("loop", 0))
|
loop = im.encoderinfo.get("loop", im.info.get("loop", 0))
|
||||||
disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE))
|
disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE))
|
||||||
|
@ -1119,10 +1119,10 @@ def _write_multiple_frames(im, fp, chunk, rawmode, default_image, append_images)
|
||||||
frame_count = 0
|
frame_count = 0
|
||||||
for im_seq in chain:
|
for im_seq in chain:
|
||||||
for im_frame in ImageSequence.Iterator(im_seq):
|
for im_frame in ImageSequence.Iterator(im_seq):
|
||||||
if im_frame.mode == rawmode:
|
if im_frame.mode == mode:
|
||||||
im_frame = im_frame.copy()
|
im_frame = im_frame.copy()
|
||||||
else:
|
else:
|
||||||
im_frame = im_frame.convert(rawmode)
|
im_frame = im_frame.convert(mode)
|
||||||
encoderinfo = im.encoderinfo.copy()
|
encoderinfo = im.encoderinfo.copy()
|
||||||
if isinstance(duration, (list, tuple)):
|
if isinstance(duration, (list, tuple)):
|
||||||
encoderinfo["duration"] = duration[frame_count]
|
encoderinfo["duration"] = duration[frame_count]
|
||||||
|
@ -1184,8 +1184,8 @@ def _write_multiple_frames(im, fp, chunk, rawmode, default_image, append_images)
|
||||||
|
|
||||||
# default image IDAT (if it exists)
|
# default image IDAT (if it exists)
|
||||||
if default_image:
|
if default_image:
|
||||||
if im.mode != rawmode:
|
if im.mode != mode:
|
||||||
im = im.convert(rawmode)
|
im = im.convert(mode)
|
||||||
ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)])
|
ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)])
|
||||||
|
|
||||||
seq_num = 0
|
seq_num = 0
|
||||||
|
@ -1262,6 +1262,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
|
||||||
size = im.size
|
size = im.size
|
||||||
mode = im.mode
|
mode = im.mode
|
||||||
|
|
||||||
|
outmode = mode
|
||||||
if mode == "P":
|
if mode == "P":
|
||||||
#
|
#
|
||||||
# attempt to minimize storage requirements for palette images
|
# attempt to minimize storage requirements for palette images
|
||||||
|
@ -1282,7 +1283,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
|
||||||
bits = 2
|
bits = 2
|
||||||
else:
|
else:
|
||||||
bits = 4
|
bits = 4
|
||||||
mode = f"{mode};{bits}"
|
outmode += f";{bits}"
|
||||||
|
|
||||||
# encoder options
|
# encoder options
|
||||||
im.encoderconfig = (
|
im.encoderconfig = (
|
||||||
|
@ -1294,7 +1295,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
|
||||||
|
|
||||||
# get the corresponding PNG mode
|
# get the corresponding PNG mode
|
||||||
try:
|
try:
|
||||||
rawmode, bit_depth, color_type = _OUTMODES[mode]
|
rawmode, bit_depth, color_type = _OUTMODES[outmode]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
msg = f"cannot write mode {mode} as PNG"
|
msg = f"cannot write mode {mode} as PNG"
|
||||||
raise OSError(msg) from e
|
raise OSError(msg) from e
|
||||||
|
@ -1415,7 +1416,7 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
|
||||||
|
|
||||||
if save_all:
|
if save_all:
|
||||||
im = _write_multiple_frames(
|
im = _write_multiple_frames(
|
||||||
im, fp, chunk, rawmode, default_image, append_images
|
im, fp, chunk, mode, rawmode, default_image, append_images
|
||||||
)
|
)
|
||||||
if im:
|
if im:
|
||||||
ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)])
|
ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user