Added type hints

This commit is contained in:
Andrew Murray 2024-06-09 07:12:05 +10:00
parent 0a45381c2b
commit 56fa3c658a
8 changed files with 60 additions and 27 deletions

View File

@ -558,7 +558,11 @@ def _normalize_palette(im, palette, info):
return im return im
def _write_single_frame(im, fp, palette): def _write_single_frame(
im: Image.Image,
fp: IO[bytes],
palette: bytes | bytearray | list[int] | ImagePalette.ImagePalette,
) -> None:
im_out = _normalize_mode(im) im_out = _normalize_mode(im)
for k, v in im_out.info.items(): for k, v in im_out.info.items():
im.encoderinfo.setdefault(k, v) im.encoderinfo.setdefault(k, v)
@ -579,7 +583,9 @@ def _write_single_frame(im, fp, palette):
fp.write(b"\0") # end of image data fp.write(b"\0") # end of image data
def _getbbox(base_im, im_frame): def _getbbox(
base_im: Image.Image, im_frame: Image.Image
) -> tuple[Image.Image, tuple[int, int, int, int]]:
if _get_palette_bytes(im_frame) != _get_palette_bytes(base_im): if _get_palette_bytes(im_frame) != _get_palette_bytes(base_im):
im_frame = im_frame.convert("RGBA") im_frame = im_frame.convert("RGBA")
base_im = base_im.convert("RGBA") base_im = base_im.convert("RGBA")
@ -790,7 +796,7 @@ def _write_local_header(fp, im, offset, flags):
fp.write(o8(8)) # bits fp.write(o8(8)) # bits
def _save_netpbm(im, fp, filename): def _save_netpbm(im: Image.Image, fp: IO[bytes], filename: str) -> None:
# Unused by default. # Unused by default.
# To use, uncomment the register_save call at the end of the file. # To use, uncomment the register_save call at the end of the file.
# #
@ -821,6 +827,7 @@ def _save_netpbm(im, fp, filename):
) )
# Allow ppmquant to receive SIGPIPE if ppmtogif exits # Allow ppmquant to receive SIGPIPE if ppmtogif exits
assert quant_proc.stdout is not None
quant_proc.stdout.close() quant_proc.stdout.close()
retcode = quant_proc.wait() retcode = quant_proc.wait()
@ -1080,7 +1087,7 @@ def getdata(im, offset=(0, 0), **params):
class Collector: class Collector:
data = [] data = []
def write(self, data): def write(self, data: bytes) -> None:
self.data.append(data) self.data.append(data)
im.load() # make sure raster data is available im.load() # make sure raster data is available

View File

@ -21,6 +21,7 @@ See the GIMP distribution for more information.)
from __future__ import annotations from __future__ import annotations
from math import log, pi, sin, sqrt from math import log, pi, sin, sqrt
from typing import IO, Callable
from ._binary import o8 from ._binary import o8
@ -28,7 +29,7 @@ EPSILON = 1e-10
"""""" # Enable auto-doc for data member """""" # Enable auto-doc for data member
def linear(middle, pos): def linear(middle: float, pos: float) -> float:
if pos <= middle: if pos <= middle:
if middle < EPSILON: if middle < EPSILON:
return 0.0 return 0.0
@ -43,19 +44,19 @@ def linear(middle, pos):
return 0.5 + 0.5 * pos / middle return 0.5 + 0.5 * pos / middle
def curved(middle, pos): def curved(middle: float, pos: float) -> float:
return pos ** (log(0.5) / log(max(middle, EPSILON))) return pos ** (log(0.5) / log(max(middle, EPSILON)))
def sine(middle, pos): def sine(middle: float, pos: float) -> float:
return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0 return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0
def sphere_increasing(middle, pos): def sphere_increasing(middle: float, pos: float) -> float:
return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2) return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2)
def sphere_decreasing(middle, pos): def sphere_decreasing(middle: float, pos: float) -> float:
return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2) return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2)
@ -64,9 +65,22 @@ SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing]
class GradientFile: class GradientFile:
gradient = None gradient: (
list[
tuple[
float,
float,
float,
list[float],
list[float],
Callable[[float, float], float],
]
]
| None
) = None
def getpalette(self, entries=256): def getpalette(self, entries: int = 256) -> tuple[bytes, str]:
assert self.gradient is not None
palette = [] palette = []
ix = 0 ix = 0
@ -101,7 +115,7 @@ class GradientFile:
class GimpGradientFile(GradientFile): class GimpGradientFile(GradientFile):
"""File handler for GIMP's gradient format.""" """File handler for GIMP's gradient format."""
def __init__(self, fp): def __init__(self, fp: IO[bytes]) -> None:
if fp.readline()[:13] != b"GIMP Gradient": if fp.readline()[:13] != b"GIMP Gradient":
msg = "not a GIMP gradient file" msg = "not a GIMP gradient file"
raise SyntaxError(msg) raise SyntaxError(msg)
@ -114,7 +128,16 @@ class GimpGradientFile(GradientFile):
count = int(line) count = int(line)
gradient = [] gradient: list[
tuple[
float,
float,
float,
list[float],
list[float],
Callable[[float, float], float],
]
] = []
for i in range(count): for i in range(count):
s = fp.readline().split() s = fp.readline().split()

View File

@ -2470,7 +2470,7 @@ class Image:
save_all = params.pop("save_all", False) save_all = params.pop("save_all", False)
self.encoderinfo = params self.encoderinfo = params
self.encoderconfig = () self.encoderconfig: tuple[Any, ...] = ()
preinit() preinit()

View File

@ -30,7 +30,7 @@ from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath
class Pen: class Pen:
"""Stores an outline color and width.""" """Stores an outline color and width."""
def __init__(self, color, width=1, opacity=255): def __init__(self, color: str, width: int = 1, opacity: int = 255) -> None:
self.color = ImageColor.getrgb(color) self.color = ImageColor.getrgb(color)
self.width = width self.width = width
@ -38,7 +38,7 @@ class Pen:
class Brush: class Brush:
"""Stores a fill color""" """Stores a fill color"""
def __init__(self, color, opacity=255): def __init__(self, color: str, opacity: int = 255) -> None:
self.color = ImageColor.getrgb(color) self.color = ImageColor.getrgb(color)
@ -63,7 +63,7 @@ class Draw:
self.image = image self.image = image
self.transform = None self.transform = None
def flush(self): def flush(self) -> Image.Image:
return self.image return self.image
def render(self, op, xy, pen, brush=None): def render(self, op, xy, pen, brush=None):

View File

@ -37,7 +37,7 @@ from . import Image
_pilbitmap_ok = None _pilbitmap_ok = None
def _pilbitmap_check(): def _pilbitmap_check() -> int:
global _pilbitmap_ok global _pilbitmap_ok
if _pilbitmap_ok is None: if _pilbitmap_ok is None:
try: try:
@ -162,7 +162,7 @@ class PhotoImage:
""" """
return self.__size[1] return self.__size[1]
def paste(self, im): def paste(self, im: Image.Image) -> None:
""" """
Paste a PIL image into the photo image. Note that this can Paste a PIL image into the photo image. Note that this can
be very slow if the photo image is displayed. be very slow if the photo image is displayed.
@ -254,7 +254,7 @@ class BitmapImage:
return str(self.__photo) return str(self.__photo)
def getimage(photo): def getimage(photo: PhotoImage) -> Image.Image:
"""Copies the contents of a PhotoImage to a PIL image memory.""" """Copies the contents of a PhotoImage to a PIL image memory."""
im = Image.new("RGBA", (photo.width(), photo.height())) im = Image.new("RGBA", (photo.width(), photo.height()))
block = im.im block = im.im

View File

@ -18,6 +18,7 @@ from __future__ import annotations
import io import io
import os import os
import struct import struct
from typing import IO
from . import Image, ImageFile, ImagePalette, _binary from . import Image, ImageFile, ImagePalette, _binary
@ -328,7 +329,7 @@ def _accept(prefix: bytes) -> bool:
# Save support # Save support
def _save(im, fp, filename): def _save(im: Image.Image, fp: IO[bytes], filename: str) -> None:
# Get the keyword arguments # Get the keyword arguments
info = im.encoderinfo info = im.encoderinfo

View File

@ -14,6 +14,8 @@
# #
from __future__ import annotations from __future__ import annotations
from typing import IO
from ._binary import o8 from ._binary import o8
@ -22,8 +24,8 @@ class PaletteFile:
rawmode = "RGB" rawmode = "RGB"
def __init__(self, fp): def __init__(self, fp: IO[bytes]) -> None:
self.palette = [(i, i, i) for i in range(256)] palette = [o8(i) * 3 for i in range(256)]
while True: while True:
s = fp.readline() s = fp.readline()
@ -44,9 +46,9 @@ class PaletteFile:
g = b = r g = b = r
if 0 <= i <= 255: if 0 <= i <= 255:
self.palette[i] = o8(r) + o8(g) + o8(b) palette[i] = o8(r) + o8(g) + o8(b)
self.palette = b"".join(self.palette) self.palette = b"".join(palette)
def getpalette(self) -> tuple[bytes, str]: def getpalette(self) -> tuple[bytes, str]:
return self.palette, self.rawmode return self.palette, self.rawmode

View File

@ -50,7 +50,7 @@ import warnings
from collections.abc import MutableMapping from collections.abc import MutableMapping
from fractions import Fraction from fractions import Fraction
from numbers import Number, Rational from numbers import Number, Rational
from typing import TYPE_CHECKING, Any, Callable from typing import IO, TYPE_CHECKING, Any, Callable
from . import ExifTags, Image, ImageFile, ImageOps, ImagePalette, TiffTags from . import ExifTags, Image, ImageFile, ImageOps, ImagePalette, TiffTags
from ._binary import i16be as i16 from ._binary import i16be as i16
@ -2149,7 +2149,7 @@ class AppendingTiffWriter:
self.rewriteLastLong(offset) self.rewriteLastLong(offset)
def _save_all(im, fp, filename): def _save_all(im: Image.Image, fp: IO[bytes], filename: str) -> None:
encoderinfo = im.encoderinfo.copy() encoderinfo = im.encoderinfo.copy()
encoderconfig = im.encoderconfig encoderconfig = im.encoderconfig
append_images = list(encoderinfo.get("append_images", [])) append_images = list(encoderinfo.get("append_images", []))