mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-03-23 03:24:13 +03:00
doc string for ani plugin
This commit is contained in:
parent
cd4ee0473c
commit
da093b9fef
|
@ -16,14 +16,23 @@ def _accept(s):
|
||||||
def _save_frame(im: Image.Image, fp: BytesIO, filename: str, info: dict):
|
def _save_frame(im: Image.Image, fp: BytesIO, filename: str, info: dict):
|
||||||
fp.write(b"\0\0\2\0")
|
fp.write(b"\0\0\2\0")
|
||||||
bmp = True
|
bmp = True
|
||||||
sizes = info.get(
|
s = im.encoderinfo.get(
|
||||||
"sizes",
|
"sizes",
|
||||||
[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
|
[(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)],
|
||||||
)
|
)
|
||||||
hotspots = info.get("hotspots", [(0, 0) for i in range(len(sizes))])
|
h = im.encoderinfo.get("hotspots", [(0, 0) for i in range(len(s))])
|
||||||
|
|
||||||
if len(hotspots) != len(sizes):
|
if len(hotspots) != len(sizes):
|
||||||
raise ValueError("Number of hotspots must be equal to number of cursor sizes")
|
raise ValueError("Number of hotspots must be equal to number of cursor sizes")
|
||||||
|
|
||||||
|
# sort and remove duplicate sizes
|
||||||
|
sizes = []
|
||||||
|
hotspots = []
|
||||||
|
for size, hotspot in zip(*sorted(zip(s, h), lambda x: x[0])):
|
||||||
|
if size not in sizes:
|
||||||
|
sizes.append(size)
|
||||||
|
hotspots.append(hotspots)
|
||||||
|
|
||||||
frames = []
|
frames = []
|
||||||
width, height = im.size
|
width, height = im.size
|
||||||
for size in sorted(set(sizes)):
|
for size in sorted(set(sizes)):
|
||||||
|
@ -161,7 +170,7 @@ def _write_multiple_frames(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
|
|
||||||
if seq:
|
if seq:
|
||||||
if len(rate) != len(seq):
|
if len(rate) != len(seq):
|
||||||
raise ValueError("Length of rate must match rate of sequence")
|
raise ValueError("Length of rate must match length of sequence")
|
||||||
else:
|
else:
|
||||||
if len(rate) != len(frames):
|
if len(rate) != len(frames):
|
||||||
raise ValueError("Length of rate must match number of frames")
|
raise ValueError("Length of rate must match number of frames")
|
||||||
|
@ -344,18 +353,49 @@ class AniFile:
|
||||||
im = CurImagePlugin.CurImageFile(BytesIO(data))
|
im = CurImagePlugin.CurImageFile(BytesIO(data))
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
def sizes(self):
|
||||||
|
return [data['size'] for data in self.image_data]
|
||||||
|
|
||||||
|
def hotspots(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniImageFile(ImageFile.ImageFile):
|
class AniImageFile(ImageFile.ImageFile):
|
||||||
|
"""
|
||||||
|
PIL read-only image support for Microsoft Windows .ani files.
|
||||||
|
|
||||||
|
By default the largest resolution image and first frame in the file will
|
||||||
|
be loaded.
|
||||||
|
|
||||||
|
The info dictionary has four keys:
|
||||||
|
'seq': the sequence of the frames used for animation.
|
||||||
|
'rate': the rate (in 1/60th of a second) for each frame in the sequence.
|
||||||
|
'frames': the number of frames in the file.
|
||||||
|
'sizes': a list of the sizes available for the current frame.
|
||||||
|
'hotspots': a list of the cursor hotspots for a given frame.
|
||||||
|
|
||||||
|
Saving is similar to GIF. Arguments for encoding are:
|
||||||
|
'sizes': The sizes of the cursor (used for scaling by windows).
|
||||||
|
'hotspots': The hotspot for each size, with (0, 0) being the top left.
|
||||||
|
'append_images': The frames for animation. Please note that the sizes and
|
||||||
|
hotspots are shared across each frame.
|
||||||
|
'seq': The sequence of frames, zero indexed.
|
||||||
|
'rate': The rate for each frame in the seq. Must be the same length as seq or
|
||||||
|
equal to the number of frames if seq is not passed.
|
||||||
|
"""
|
||||||
|
|
||||||
format = "ANI"
|
format = "ANI"
|
||||||
format_description = "Windows Animated Cursor"
|
format_description = "Windows Animated Cursor"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
self.ani = AniFile(self.fp)
|
self.ani = AniFile(self.fp)
|
||||||
|
self.info["seq"] = self.ani.seq
|
||||||
|
self.info["rate"] = self.ani.rate
|
||||||
|
self.info["frames"] = self.ani.anih["nFrames"]
|
||||||
|
|
||||||
self.frame = 0
|
self.frame = 0
|
||||||
self.seek(0)
|
self.seek(0)
|
||||||
self.size = self.im.size
|
self.size = self.im.size
|
||||||
self.info["seq"] = self.ani.seq
|
|
||||||
self.info["rate"] = self.ani.rate
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
|
@ -370,11 +410,12 @@ class AniImageFile(ImageFile.ImageFile):
|
||||||
def load(self):
|
def load(self):
|
||||||
im = self.ani.frame(self.frame)
|
im = self.ani.frame(self.frame)
|
||||||
self.info["sizes"] = im.info["sizes"]
|
self.info["sizes"] = im.info["sizes"]
|
||||||
|
self.info["hotspots"] = im.info["hotspots"]
|
||||||
self.im = im.im
|
self.im = im.im
|
||||||
self.mode = im.mode
|
self.mode = im.mode
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame):
|
||||||
if frame > self.ani.anih["nFrames"]:
|
if frame > self.info["frames"]:
|
||||||
raise ValueError("Frame index out of animation bounds")
|
raise ValueError("Frame index out of animation bounds")
|
||||||
|
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
|
Loading…
Reference in New Issue
Block a user