Created _write_single_frame and _write_multiple_frames from _save

This commit is contained in:
Andrew Murray 2017-02-18 21:23:42 +11:00
parent d45f1d835b
commit 87a14ce6de

View File

@ -311,44 +311,36 @@ def _convert_mode(im, initial_call=False):
return im.convert("P") return im.convert("P")
return im.convert("L") return im.convert("L")
def _write_single_frame(im, fp, palette):
def _save_all(im, fp, filename):
_save(im, fp, filename, save_all=True)
def _save(im, fp, filename, save_all=False):
im.encoderinfo.update(im.info)
if _imaging_gif:
# call external driver
try:
_imaging_gif.save(im, fp, filename)
return
except IOError:
pass # write uncompressed file
if im.mode in RAWMODE: if im.mode in RAWMODE:
im_out = im.copy() im_out = im.copy()
else: else:
im_out = _convert_mode(im, True) im_out = _convert_mode(im, True)
# header for s in _get_global_header(im_out, palette, im.encoderinfo):
try: fp.write(s)
palette = im.encoderinfo["palette"]
except KeyError:
palette = None
im.encoderinfo["optimize"] = im.encoderinfo.get("optimize", True)
if save_all: # local image header
# To specify duration, add the time in milliseconds to getdata(), flags = 0
# e.g. getdata(im_frame, duration=1000) if get_interlace(im):
flags = flags | 64
_get_local_header(fp, im, (0, 0), flags)
im_out.encoderconfig = (8, get_interlace(im))
ImageFile._save(im_out, fp, [("gif", (0, 0)+im.size, 0,
RAWMODE[im_out.mode])])
fp.write(b"\0") # end of image data
def _write_multiple_frames(im, fp, palette):
if "duration" in im.encoderinfo: if "duration" in im.encoderinfo:
duration = im.encoderinfo["duration"] duration = im.encoderinfo["duration"]
else: else:
duration = None duration = None
im_frames = [] im_frames = []
append_images = im.encoderinfo.get("append_images", [])
frame_count = 0 frame_count = 0
for imSequence in [im]+append_images: for imSequence in [im]+im.encoderinfo.get("append_images", []):
for im_frame in ImageSequence.Iterator(imSequence): for im_frame in ImageSequence.Iterator(imSequence):
im_frame = _convert_mode(im_frame) im_frame = _convert_mode(im_frame)
@ -375,9 +367,7 @@ def _save(im, fp, filename, save_all=False):
'bbox':bbox, 'bbox':bbox,
'encoderinfo':encoderinfo 'encoderinfo':encoderinfo
}) })
if len(im_frames) < 2: if len(im_frames) > 1:
save_all = False
else:
for frame_data in im_frames: for frame_data in im_frames:
im_frame = frame_data['im'] im_frame = frame_data['im']
if not frame_data['bbox']: if not frame_data['bbox']:
@ -393,21 +383,31 @@ def _save(im, fp, filename, save_all=False):
im_frame = im_frame.crop(frame_data['bbox']) im_frame = im_frame.crop(frame_data['bbox'])
offset = frame_data['bbox'][:2] offset = frame_data['bbox'][:2]
_write_frame_data(fp, im_frame, offset, frame_data['encoderinfo']) _write_frame_data(fp, im_frame, offset, frame_data['encoderinfo'])
if not save_all: return True
for s in _get_global_header(im_out, palette, im.encoderinfo):
fp.write(s)
# local image header def _save_all(im, fp, filename):
flags = 0 _save(im, fp, filename, save_all=True)
if get_interlace(im):
flags = flags | 64
_get_local_header(fp, im, (0, 0), flags)
im_out.encoderconfig = (8, get_interlace(im))
ImageFile._save(im_out, fp, [("gif", (0, 0)+im.size, 0,
RAWMODE[im_out.mode])])
fp.write(b"\0") # end of image data def _save(im, fp, filename, save_all=False):
im.encoderinfo.update(im.info)
if _imaging_gif:
# call external driver
try:
_imaging_gif.save(im, fp, filename)
return
except IOError:
pass # write uncompressed file
# header
try:
palette = im.encoderinfo["palette"]
except KeyError:
palette = None
im.encoderinfo["optimize"] = im.encoderinfo.get("optimize", True)
if not save_all or not _write_multiple_frames(im, fp, palette):
_write_single_frame(im, fp, palette)
fp.write(b";") # end of file fp.write(b";") # end of file
@ -728,6 +728,8 @@ def _write_frame_data(fp, im_frame, offset, params):
finally: finally:
del im_frame.encoderinfo del im_frame.encoderinfo
# To specify duration, add the time in milliseconds to getdata(),
# e.g. getdata(im_frame, duration=1000)
def getdata(im, offset=(0, 0), **params): def getdata(im, offset=(0, 0), **params):
"""Return a list of strings representing this image. """Return a list of strings representing this image.
The first string is a local image header, the rest contains The first string is a local image header, the rest contains