Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ImageType as alias for Image.Image #7639

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions src/PIL/ImageChops.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

from __future__ import annotations

from . import Image
from . import Image, ImageType


def constant(image: Image.Image, value: int) -> Image.Image:
def constant(image: ImageType, value: int) -> ImageType:
"""Fill a channel with a given gray level.

:rtype: :py:class:`~PIL.Image.Image`
Expand All @@ -29,7 +29,7 @@ def constant(image: Image.Image, value: int) -> Image.Image:
return Image.new("L", image.size, value)


def duplicate(image: Image.Image) -> Image.Image:
def duplicate(image: ImageType) -> ImageType:
"""Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`.

:rtype: :py:class:`~PIL.Image.Image`
Expand All @@ -38,7 +38,7 @@ def duplicate(image: Image.Image) -> Image.Image:
return image.copy()


def invert(image: Image.Image) -> Image.Image:
def invert(image: ImageType) -> ImageType:
"""
Invert an image (channel). ::

Expand All @@ -51,7 +51,7 @@ def invert(image: Image.Image) -> Image.Image:
return image._new(image.im.chop_invert())


def lighter(image1: Image.Image, image2: Image.Image) -> Image.Image:
def lighter(image1: ImageType, image2: ImageType) -> ImageType:
"""
Compares the two images, pixel by pixel, and returns a new image containing
the lighter values. ::
Expand All @@ -66,7 +66,7 @@ def lighter(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_lighter(image2.im))


def darker(image1: Image.Image, image2: Image.Image) -> Image.Image:
def darker(image1: ImageType, image2: ImageType) -> ImageType:
"""
Compares the two images, pixel by pixel, and returns a new image containing
the darker values. ::
Expand All @@ -81,7 +81,7 @@ def darker(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_darker(image2.im))


def difference(image1: Image.Image, image2: Image.Image) -> Image.Image:
def difference(image1: ImageType, image2: ImageType) -> ImageType:
"""
Returns the absolute value of the pixel-by-pixel difference between the two
images. ::
Expand All @@ -96,7 +96,7 @@ def difference(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_difference(image2.im))


def multiply(image1: Image.Image, image2: Image.Image) -> Image.Image:
def multiply(image1: ImageType, image2: ImageType) -> ImageType:
"""
Superimposes two images on top of each other.

Expand All @@ -113,7 +113,7 @@ def multiply(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_multiply(image2.im))


def screen(image1: Image.Image, image2: Image.Image) -> Image.Image:
def screen(image1: ImageType, image2: ImageType) -> ImageType:
"""
Superimposes two inverted images on top of each other. ::

Expand All @@ -127,7 +127,7 @@ def screen(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_screen(image2.im))


def soft_light(image1: Image.Image, image2: Image.Image) -> Image.Image:
def soft_light(image1: ImageType, image2: ImageType) -> ImageType:
"""
Superimposes two images on top of each other using the Soft Light algorithm

Expand All @@ -139,7 +139,7 @@ def soft_light(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_soft_light(image2.im))


def hard_light(image1: Image.Image, image2: Image.Image) -> Image.Image:
def hard_light(image1: ImageType, image2: ImageType) -> ImageType:
"""
Superimposes two images on top of each other using the Hard Light algorithm

Expand All @@ -151,7 +151,7 @@ def hard_light(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_hard_light(image2.im))


def overlay(image1: Image.Image, image2: Image.Image) -> Image.Image:
def overlay(image1: ImageType, image2: ImageType) -> ImageType:
"""
Superimposes two images on top of each other using the Overlay algorithm

Expand All @@ -164,8 +164,11 @@ def overlay(image1: Image.Image, image2: Image.Image) -> Image.Image:


def add(
image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0
) -> Image.Image:
image1: ImageType,
image2: ImageType,
scale: float = 1.0,
offset: float = 0,
) -> ImageType:
"""
Adds two images, dividing the result by scale and adding the
offset. If omitted, scale defaults to 1.0, and offset to 0.0. ::
Expand All @@ -181,8 +184,11 @@ def add(


def subtract(
image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0
) -> Image.Image:
image1: ImageType,
image2: ImageType,
scale: float = 1.0,
offset: float = 0,
) -> ImageType:
"""
Subtracts two images, dividing the result by scale and adding the offset.
If omitted, scale defaults to 1.0, and offset to 0.0. ::
Expand All @@ -197,7 +203,7 @@ def subtract(
return image1._new(image1.im.chop_subtract(image2.im, scale, offset))


def add_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image:
def add_modulo(image1: ImageType, image2: ImageType) -> ImageType:
"""Add two images, without clipping the result. ::

out = ((image1 + image2) % MAX)
Expand All @@ -210,7 +216,7 @@ def add_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_add_modulo(image2.im))


def subtract_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image:
def subtract_modulo(image1: ImageType, image2: ImageType) -> ImageType:
"""Subtract two images, without clipping the result. ::

out = ((image1 - image2) % MAX)
Expand All @@ -223,7 +229,7 @@ def subtract_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_subtract_modulo(image2.im))


def logical_and(image1: Image.Image, image2: Image.Image) -> Image.Image:
def logical_and(image1: ImageType, image2: ImageType) -> ImageType:
"""Logical AND between two images.

Both of the images must have mode "1". If you would like to perform a
Expand All @@ -241,7 +247,7 @@ def logical_and(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_and(image2.im))


def logical_or(image1: Image.Image, image2: Image.Image) -> Image.Image:
def logical_or(image1: ImageType, image2: ImageType) -> ImageType:
"""Logical OR between two images.

Both of the images must have mode "1". ::
Expand All @@ -256,7 +262,7 @@ def logical_or(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_or(image2.im))


def logical_xor(image1: Image.Image, image2: Image.Image) -> Image.Image:
def logical_xor(image1: ImageType, image2: ImageType) -> ImageType:
"""Logical XOR between two images.

Both of the images must have mode "1". ::
Expand All @@ -271,7 +277,7 @@ def logical_xor(image1: Image.Image, image2: Image.Image) -> Image.Image:
return image1._new(image1.im.chop_xor(image2.im))


def blend(image1: Image.Image, image2: Image.Image, alpha: float) -> Image.Image:
def blend(image1: ImageType, image2: ImageType, alpha: float) -> ImageType:
"""Blend images using constant transparency weight. Alias for
:py:func:`PIL.Image.blend`.

Expand All @@ -281,9 +287,7 @@ def blend(image1: Image.Image, image2: Image.Image, alpha: float) -> Image.Image
return Image.blend(image1, image2, alpha)


def composite(
image1: Image.Image, image2: Image.Image, mask: Image.Image
) -> Image.Image:
def composite(image1: ImageType, image2: ImageType, mask: ImageType) -> ImageType:
"""Create composite using transparency mask. Alias for
:py:func:`PIL.Image.composite`.

Expand All @@ -293,7 +297,7 @@ def composite(
return Image.composite(image1, image2, mask)


def offset(image: Image.Image, xoffset: int, yoffset: int | None = None) -> Image.Image:
def offset(image: ImageType, xoffset: int, yoffset: int | None = None) -> ImageType:
"""Returns a copy of the image where data has been offset by the given
distances. Data wraps around the edges. If ``yoffset`` is omitted, it
is assumed to be equal to ``xoffset``.
Expand Down
14 changes: 7 additions & 7 deletions src/PIL/ImageSequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from typing import Callable

from . import Image
from . import ImageType


class Iterator:
Expand All @@ -33,14 +33,14 @@ class Iterator:
:param im: An image object.
"""

def __init__(self, im: Image.Image):
def __init__(self, im: ImageType):
if not hasattr(im, "seek"):
msg = "im must have seek method"
raise AttributeError(msg)
self.im = im
self.position = getattr(self.im, "_min_frame", 0)

def __getitem__(self, ix: int) -> Image.Image:
def __getitem__(self, ix: int) -> ImageType:
try:
self.im.seek(ix)
return self.im
Expand All @@ -51,7 +51,7 @@ def __getitem__(self, ix: int) -> Image.Image:
def __iter__(self) -> Iterator:
return self

def __next__(self) -> Image.Image:
def __next__(self) -> ImageType:
try:
self.im.seek(self.position)
self.position += 1
Expand All @@ -62,9 +62,9 @@ def __next__(self) -> Image.Image:


def all_frames(
im: Image.Image | list[Image.Image],
func: Callable[[Image.Image], Image.Image] | None = None,
) -> list[Image.Image]:
im: ImageType | list[ImageType],
func: Callable[[ImageType], ImageType] | None = None,
) -> list[ImageType]:
"""
Applies a given function to all frames in an image or a list of images.
The frames are returned as a list of separate images.
Expand Down
8 changes: 8 additions & 0 deletions src/PIL/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,11 @@ class UnidentifiedImageError(OSError):
"""

pass


def __getattr__(name: str):
hugovk marked this conversation as resolved.
Show resolved Hide resolved
if name == "ImageType":
from . import Image

return Image.Image
raise AttributeError
Loading