mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-21 22:30:33 +03:00
Added type hints (#8204)
Co-authored-by: Andrew Murray <radarhere@users.noreply.github.com>
This commit is contained in:
parent
7e1a6be767
commit
f3c3e52797
|
@ -16,8 +16,11 @@ def test_sanity() -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_register() -> None:
|
def test_register() -> None:
|
||||||
# Test registering a viewer that is not a class
|
# Test registering a viewer that is an instance
|
||||||
ImageShow.register("not a class")
|
class TestViewer(ImageShow.Viewer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
ImageShow.register(TestViewer())
|
||||||
|
|
||||||
# Restore original state
|
# Restore original state
|
||||||
ImageShow._viewers.pop()
|
ImageShow._viewers.pop()
|
||||||
|
|
|
@ -338,7 +338,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
msg = "cannot determine EPS bounding box"
|
msg = "cannot determine EPS bounding box"
|
||||||
raise OSError(msg)
|
raise OSError(msg)
|
||||||
|
|
||||||
def _find_offset(self, fp):
|
def _find_offset(self, fp: IO[bytes]) -> tuple[int, int]:
|
||||||
s = fp.read(4)
|
s = fp.read(4)
|
||||||
|
|
||||||
if s == b"%!PS":
|
if s == b"%!PS":
|
||||||
|
@ -361,7 +361,9 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
return length, offset
|
return length, offset
|
||||||
|
|
||||||
def load(self, scale=1, transparency=False):
|
def load(
|
||||||
|
self, scale: int = 1, transparency: bool = False
|
||||||
|
) -> Image.core.PixelAccess | None:
|
||||||
# Load EPS via Ghostscript
|
# Load EPS via Ghostscript
|
||||||
if self.tile:
|
if self.tile:
|
||||||
self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency)
|
self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency)
|
||||||
|
|
|
@ -45,7 +45,7 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
format_description = "Autodesk FLI/FLC Animation"
|
format_description = "Autodesk FLI/FLC Animation"
|
||||||
_close_exclusive_fp_after_loading = False
|
_close_exclusive_fp_after_loading = False
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
# HEAD
|
# HEAD
|
||||||
s = self.fp.read(128)
|
s = self.fp.read(128)
|
||||||
if not (_accept(s) and s[20:22] == b"\x00\x00"):
|
if not (_accept(s) and s[20:22] == b"\x00\x00"):
|
||||||
|
@ -83,7 +83,7 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
if i16(s, 4) == 0xF1FA:
|
if i16(s, 4) == 0xF1FA:
|
||||||
# look for palette chunk
|
# look for palette chunk
|
||||||
number_of_subchunks = i16(s, 6)
|
number_of_subchunks = i16(s, 6)
|
||||||
chunk_size = None
|
chunk_size: int | None = None
|
||||||
for _ in range(number_of_subchunks):
|
for _ in range(number_of_subchunks):
|
||||||
if chunk_size is not None:
|
if chunk_size is not None:
|
||||||
self.fp.seek(chunk_size - 6, os.SEEK_CUR)
|
self.fp.seek(chunk_size - 6, os.SEEK_CUR)
|
||||||
|
@ -96,8 +96,9 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
if not chunk_size:
|
if not chunk_size:
|
||||||
break
|
break
|
||||||
|
|
||||||
palette = [o8(r) + o8(g) + o8(b) for (r, g, b) in palette]
|
self.palette = ImagePalette.raw(
|
||||||
self.palette = ImagePalette.raw("RGB", b"".join(palette))
|
"RGB", b"".join(o8(r) + o8(g) + o8(b) for (r, g, b) in palette)
|
||||||
|
)
|
||||||
|
|
||||||
# set things up to decode first frame
|
# set things up to decode first frame
|
||||||
self.__frame = -1
|
self.__frame = -1
|
||||||
|
@ -105,7 +106,7 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
self.__rewind = self.fp.tell()
|
self.__rewind = self.fp.tell()
|
||||||
self.seek(0)
|
self.seek(0)
|
||||||
|
|
||||||
def _palette(self, palette, shift):
|
def _palette(self, palette: list[tuple[int, int, int]], shift: int) -> None:
|
||||||
# load palette
|
# load palette
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
|
|
|
@ -231,7 +231,7 @@ class FpxImageFile(ImageFile.ImageFile):
|
||||||
self._fp = self.fp
|
self._fp = self.fp
|
||||||
self.fp = None
|
self.fp = None
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if not self.fp:
|
if not self.fp:
|
||||||
self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"])
|
self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"])
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ class GbrImageFile(ImageFile.ImageFile):
|
||||||
# Data is an uncompressed block of w * h * bytes/pixel
|
# Data is an uncompressed block of w * h * bytes/pixel
|
||||||
self._data_size = width * height * color_depth
|
self._data_size = width * height * color_depth
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if not self.im:
|
if not self.im:
|
||||||
self.im = Image.core.new(self.mode, self.size)
|
self.im = Image.core.new(self.mode, self.size)
|
||||||
self.frombytes(self.fp.read(self._data_size))
|
self.frombytes(self.fp.read(self._data_size))
|
||||||
|
|
|
@ -34,11 +34,13 @@ MAGIC = b"icns"
|
||||||
HEADERSIZE = 8
|
HEADERSIZE = 8
|
||||||
|
|
||||||
|
|
||||||
def nextheader(fobj):
|
def nextheader(fobj: IO[bytes]) -> tuple[bytes, int]:
|
||||||
return struct.unpack(">4sI", fobj.read(HEADERSIZE))
|
return struct.unpack(">4sI", fobj.read(HEADERSIZE))
|
||||||
|
|
||||||
|
|
||||||
def read_32t(fobj, start_length, size):
|
def read_32t(
|
||||||
|
fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int]
|
||||||
|
) -> dict[str, Image.Image]:
|
||||||
# The 128x128 icon seems to have an extra header for some reason.
|
# The 128x128 icon seems to have an extra header for some reason.
|
||||||
(start, length) = start_length
|
(start, length) = start_length
|
||||||
fobj.seek(start)
|
fobj.seek(start)
|
||||||
|
@ -49,7 +51,9 @@ def read_32t(fobj, start_length, size):
|
||||||
return read_32(fobj, (start + 4, length - 4), size)
|
return read_32(fobj, (start + 4, length - 4), size)
|
||||||
|
|
||||||
|
|
||||||
def read_32(fobj, start_length, size):
|
def read_32(
|
||||||
|
fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int]
|
||||||
|
) -> dict[str, Image.Image]:
|
||||||
"""
|
"""
|
||||||
Read a 32bit RGB icon resource. Seems to be either uncompressed or
|
Read a 32bit RGB icon resource. Seems to be either uncompressed or
|
||||||
an RLE packbits-like scheme.
|
an RLE packbits-like scheme.
|
||||||
|
@ -72,14 +76,14 @@ def read_32(fobj, start_length, size):
|
||||||
byte = fobj.read(1)
|
byte = fobj.read(1)
|
||||||
if not byte:
|
if not byte:
|
||||||
break
|
break
|
||||||
byte = byte[0]
|
byte_int = byte[0]
|
||||||
if byte & 0x80:
|
if byte_int & 0x80:
|
||||||
blocksize = byte - 125
|
blocksize = byte_int - 125
|
||||||
byte = fobj.read(1)
|
byte = fobj.read(1)
|
||||||
for i in range(blocksize):
|
for i in range(blocksize):
|
||||||
data.append(byte)
|
data.append(byte)
|
||||||
else:
|
else:
|
||||||
blocksize = byte + 1
|
blocksize = byte_int + 1
|
||||||
data.append(fobj.read(blocksize))
|
data.append(fobj.read(blocksize))
|
||||||
bytesleft -= blocksize
|
bytesleft -= blocksize
|
||||||
if bytesleft <= 0:
|
if bytesleft <= 0:
|
||||||
|
@ -92,7 +96,9 @@ def read_32(fobj, start_length, size):
|
||||||
return {"RGB": im}
|
return {"RGB": im}
|
||||||
|
|
||||||
|
|
||||||
def read_mk(fobj, start_length, size):
|
def read_mk(
|
||||||
|
fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int]
|
||||||
|
) -> dict[str, Image.Image]:
|
||||||
# Alpha masks seem to be uncompressed
|
# Alpha masks seem to be uncompressed
|
||||||
start = start_length[0]
|
start = start_length[0]
|
||||||
fobj.seek(start)
|
fobj.seek(start)
|
||||||
|
@ -102,10 +108,14 @@ def read_mk(fobj, start_length, size):
|
||||||
return {"A": band}
|
return {"A": band}
|
||||||
|
|
||||||
|
|
||||||
def read_png_or_jpeg2000(fobj, start_length, size):
|
def read_png_or_jpeg2000(
|
||||||
|
fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int]
|
||||||
|
) -> dict[str, Image.Image]:
|
||||||
(start, length) = start_length
|
(start, length) = start_length
|
||||||
fobj.seek(start)
|
fobj.seek(start)
|
||||||
sig = fobj.read(12)
|
sig = fobj.read(12)
|
||||||
|
|
||||||
|
im: Image.Image
|
||||||
if sig[:8] == b"\x89PNG\x0d\x0a\x1a\x0a":
|
if sig[:8] == b"\x89PNG\x0d\x0a\x1a\x0a":
|
||||||
fobj.seek(start)
|
fobj.seek(start)
|
||||||
im = PngImagePlugin.PngImageFile(fobj)
|
im = PngImagePlugin.PngImageFile(fobj)
|
||||||
|
@ -164,12 +174,12 @@ class IcnsFile:
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, fobj):
|
def __init__(self, fobj: IO[bytes]) -> None:
|
||||||
"""
|
"""
|
||||||
fobj is a file-like object as an icns resource
|
fobj is a file-like object as an icns resource
|
||||||
"""
|
"""
|
||||||
# signature : (start, length)
|
# signature : (start, length)
|
||||||
self.dct = dct = {}
|
self.dct = {}
|
||||||
self.fobj = fobj
|
self.fobj = fobj
|
||||||
sig, filesize = nextheader(fobj)
|
sig, filesize = nextheader(fobj)
|
||||||
if not _accept(sig):
|
if not _accept(sig):
|
||||||
|
@ -183,11 +193,11 @@ class IcnsFile:
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
i += HEADERSIZE
|
i += HEADERSIZE
|
||||||
blocksize -= HEADERSIZE
|
blocksize -= HEADERSIZE
|
||||||
dct[sig] = (i, blocksize)
|
self.dct[sig] = (i, blocksize)
|
||||||
fobj.seek(blocksize, io.SEEK_CUR)
|
fobj.seek(blocksize, io.SEEK_CUR)
|
||||||
i += blocksize
|
i += blocksize
|
||||||
|
|
||||||
def itersizes(self):
|
def itersizes(self) -> list[tuple[int, int, int]]:
|
||||||
sizes = []
|
sizes = []
|
||||||
for size, fmts in self.SIZES.items():
|
for size, fmts in self.SIZES.items():
|
||||||
for fmt, reader in fmts:
|
for fmt, reader in fmts:
|
||||||
|
@ -196,14 +206,14 @@ class IcnsFile:
|
||||||
break
|
break
|
||||||
return sizes
|
return sizes
|
||||||
|
|
||||||
def bestsize(self):
|
def bestsize(self) -> tuple[int, int, int]:
|
||||||
sizes = self.itersizes()
|
sizes = self.itersizes()
|
||||||
if not sizes:
|
if not sizes:
|
||||||
msg = "No 32bit icon resources found"
|
msg = "No 32bit icon resources found"
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
return max(sizes)
|
return max(sizes)
|
||||||
|
|
||||||
def dataforsize(self, size):
|
def dataforsize(self, size: tuple[int, int, int]) -> dict[str, Image.Image]:
|
||||||
"""
|
"""
|
||||||
Get an icon resource as {channel: array}. Note that
|
Get an icon resource as {channel: array}. Note that
|
||||||
the arrays are bottom-up like windows bitmaps and will likely
|
the arrays are bottom-up like windows bitmaps and will likely
|
||||||
|
@ -216,18 +226,20 @@ class IcnsFile:
|
||||||
dct.update(reader(self.fobj, desc, size))
|
dct.update(reader(self.fobj, desc, size))
|
||||||
return dct
|
return dct
|
||||||
|
|
||||||
def getimage(self, size=None):
|
def getimage(
|
||||||
|
self, size: tuple[int, int] | tuple[int, int, int] | None = None
|
||||||
|
) -> Image.Image:
|
||||||
if size is None:
|
if size is None:
|
||||||
size = self.bestsize()
|
size = self.bestsize()
|
||||||
if len(size) == 2:
|
elif len(size) == 2:
|
||||||
size = (size[0], size[1], 1)
|
size = (size[0], size[1], 1)
|
||||||
channels = self.dataforsize(size)
|
channels = self.dataforsize(size)
|
||||||
|
|
||||||
im = channels.get("RGBA", None)
|
im = channels.get("RGBA")
|
||||||
if im:
|
if im:
|
||||||
return im
|
return im
|
||||||
|
|
||||||
im = channels.get("RGB").copy()
|
im = channels["RGB"].copy()
|
||||||
try:
|
try:
|
||||||
im.putalpha(channels["A"])
|
im.putalpha(channels["A"])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -268,7 +280,7 @@ class IcnsImageFile(ImageFile.ImageFile):
|
||||||
return self._size
|
return self._size
|
||||||
|
|
||||||
@size.setter
|
@size.setter
|
||||||
def size(self, value):
|
def size(self, value) -> None:
|
||||||
info_size = value
|
info_size = value
|
||||||
if info_size not in self.info["sizes"] and len(info_size) == 2:
|
if info_size not in self.info["sizes"] and len(info_size) == 2:
|
||||||
info_size = (info_size[0], info_size[1], 1)
|
info_size = (info_size[0], info_size[1], 1)
|
||||||
|
@ -287,7 +299,7 @@ class IcnsImageFile(ImageFile.ImageFile):
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
self._size = value
|
self._size = value
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if len(self.size) == 3:
|
if len(self.size) == 3:
|
||||||
self.best_size = self.size
|
self.best_size = self.size
|
||||||
self.size = (
|
self.size = (
|
||||||
|
|
|
@ -120,7 +120,7 @@ def _accept(prefix: bytes) -> bool:
|
||||||
|
|
||||||
|
|
||||||
class IcoFile:
|
class IcoFile:
|
||||||
def __init__(self, buf):
|
def __init__(self, buf) -> None:
|
||||||
"""
|
"""
|
||||||
Parse image from file-like object containing ico file data
|
Parse image from file-like object containing ico file data
|
||||||
"""
|
"""
|
||||||
|
@ -177,19 +177,19 @@ class IcoFile:
|
||||||
# ICO images are usually squares
|
# ICO images are usually squares
|
||||||
self.entry = sorted(self.entry, key=lambda x: x["square"], reverse=True)
|
self.entry = sorted(self.entry, key=lambda x: x["square"], reverse=True)
|
||||||
|
|
||||||
def sizes(self):
|
def sizes(self) -> set[tuple[int, int]]:
|
||||||
"""
|
"""
|
||||||
Get a list of all available icon sizes and color depths.
|
Get a list of all available icon sizes and color depths.
|
||||||
"""
|
"""
|
||||||
return {(h["width"], h["height"]) for h in self.entry}
|
return {(h["width"], h["height"]) for h in self.entry}
|
||||||
|
|
||||||
def getentryindex(self, size, bpp=False):
|
def getentryindex(self, size: tuple[int, int], bpp: int | bool = False) -> int:
|
||||||
for i, h in enumerate(self.entry):
|
for i, h in enumerate(self.entry):
|
||||||
if size == h["dim"] and (bpp is False or bpp == h["color_depth"]):
|
if size == h["dim"] and (bpp is False or bpp == h["color_depth"]):
|
||||||
return i
|
return i
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def getimage(self, size, bpp=False):
|
def getimage(self, size: tuple[int, int], bpp: int | bool = False) -> Image.Image:
|
||||||
"""
|
"""
|
||||||
Get an image from the icon
|
Get an image from the icon
|
||||||
"""
|
"""
|
||||||
|
@ -321,7 +321,7 @@ class IcoImageFile(ImageFile.ImageFile):
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
self._size = value
|
self._size = value
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if self.im is not None and self.im.size == self.size:
|
if self.im is not None and self.im.size == self.size:
|
||||||
# Already loaded
|
# Already loaded
|
||||||
return Image.Image.load(self)
|
return Image.Image.load(self)
|
||||||
|
@ -341,6 +341,7 @@ class IcoImageFile(ImageFile.ImageFile):
|
||||||
self.info["sizes"] = set(sizes)
|
self.info["sizes"] = set(sizes)
|
||||||
|
|
||||||
self.size = im.size
|
self.size = im.size
|
||||||
|
return None
|
||||||
|
|
||||||
def load_seek(self, pos: int) -> None:
|
def load_seek(self, pos: int) -> None:
|
||||||
# Flag the ImageFile.Parser so that it
|
# Flag the ImageFile.Parser so that it
|
||||||
|
|
|
@ -1395,7 +1395,7 @@ class Image:
|
||||||
|
|
||||||
def getcolors(
|
def getcolors(
|
||||||
self, maxcolors: int = 256
|
self, maxcolors: int = 256
|
||||||
) -> list[tuple[int, int]] | list[tuple[int, float]] | None:
|
) -> list[tuple[int, tuple[int, ...]]] | list[tuple[int, float]] | None:
|
||||||
"""
|
"""
|
||||||
Returns a list of colors used in this image.
|
Returns a list of colors used in this image.
|
||||||
|
|
||||||
|
@ -1412,7 +1412,7 @@ class Image:
|
||||||
self.load()
|
self.load()
|
||||||
if self.mode in ("1", "L", "P"):
|
if self.mode in ("1", "L", "P"):
|
||||||
h = self.im.histogram()
|
h = self.im.histogram()
|
||||||
out = [(h[i], i) for i in range(256) if h[i]]
|
out: list[tuple[int, float]] = [(h[i], i) for i in range(256) if h[i]]
|
||||||
if len(out) > maxcolors:
|
if len(out) > maxcolors:
|
||||||
return None
|
return None
|
||||||
return out
|
return out
|
||||||
|
|
|
@ -26,7 +26,7 @@ from . import Image
|
||||||
_viewers = []
|
_viewers = []
|
||||||
|
|
||||||
|
|
||||||
def register(viewer, order: int = 1) -> None:
|
def register(viewer: type[Viewer] | Viewer, order: int = 1) -> None:
|
||||||
"""
|
"""
|
||||||
The :py:func:`register` function is used to register additional viewers::
|
The :py:func:`register` function is used to register additional viewers::
|
||||||
|
|
||||||
|
@ -40,11 +40,8 @@ def register(viewer, order: int = 1) -> None:
|
||||||
Zero or a negative integer to prepend this viewer to the list,
|
Zero or a negative integer to prepend this viewer to the list,
|
||||||
a positive integer to append it.
|
a positive integer to append it.
|
||||||
"""
|
"""
|
||||||
try:
|
if isinstance(viewer, type) and issubclass(viewer, Viewer):
|
||||||
if issubclass(viewer, Viewer):
|
|
||||||
viewer = viewer()
|
viewer = viewer()
|
||||||
except TypeError:
|
|
||||||
pass # raised if viewer wasn't a class
|
|
||||||
if order > 0:
|
if order > 0:
|
||||||
_viewers.append(viewer)
|
_viewers.append(viewer)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -148,7 +148,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
||||||
if tag == (8, 10):
|
if tag == (8, 10):
|
||||||
self.tile = [("iptc", (0, 0) + self.size, offset, compression)]
|
self.tile = [("iptc", (0, 0) + self.size, offset, compression)]
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if len(self.tile) != 1 or self.tile[0][0] != "iptc":
|
if len(self.tile) != 1 or self.tile[0][0] != "iptc":
|
||||||
return ImageFile.ImageFile.load(self)
|
return ImageFile.ImageFile.load(self)
|
||||||
|
|
||||||
|
@ -176,6 +176,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
||||||
with Image.open(o) as _im:
|
with Image.open(o) as _im:
|
||||||
_im.load()
|
_im.load()
|
||||||
self.im = _im.im
|
self.im = _im.im
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
Image.register_open(IptcImageFile.format, IptcImageFile)
|
Image.register_open(IptcImageFile.format, IptcImageFile)
|
||||||
|
|
|
@ -299,7 +299,7 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
|
||||||
def reduce(self, value):
|
def reduce(self, value):
|
||||||
self._reduce = value
|
self._reduce = value
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if self.tile and self._reduce:
|
if self.tile and self._reduce:
|
||||||
power = 1 << self._reduce
|
power = 1 << self._reduce
|
||||||
adjust = power >> 1
|
adjust = power >> 1
|
||||||
|
|
|
@ -1232,7 +1232,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
val = val[math.ceil((10 + n + size) / 2) * 2 :]
|
val = val[math.ceil((10 + n + size) / 2) * 2 :]
|
||||||
return blocks
|
return blocks
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if self.tile and self.use_load_libtiff:
|
if self.tile and self.use_load_libtiff:
|
||||||
return self._load_libtiff()
|
return self._load_libtiff()
|
||||||
return super().load()
|
return super().load()
|
||||||
|
|
|
@ -50,7 +50,7 @@ class WalImageFile(ImageFile.ImageFile):
|
||||||
if next_name:
|
if next_name:
|
||||||
self.info["next_name"] = next_name
|
self.info["next_name"] = next_name
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if not self.im:
|
if not self.im:
|
||||||
self.im = Image.core.new(self.mode, self.size)
|
self.im = Image.core.new(self.mode, self.size)
|
||||||
self.frombytes(self.fp.read(self.size[0] * self.size[1]))
|
self.frombytes(self.fp.read(self.size[0] * self.size[1]))
|
||||||
|
|
|
@ -144,7 +144,7 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
while self.__physical_frame < frame:
|
while self.__physical_frame < frame:
|
||||||
self._get_next() # Advance to the requested frame
|
self._get_next() # Advance to the requested frame
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> Image.core.PixelAccess | None:
|
||||||
if _webp.HAVE_WEBPANIM:
|
if _webp.HAVE_WEBPANIM:
|
||||||
if self.__loaded != self.__logical_frame:
|
if self.__loaded != self.__logical_frame:
|
||||||
self._seek(self.__logical_frame)
|
self._seek(self.__logical_frame)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user