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 type hints to ImageChops #7617

Merged
merged 3 commits into from
Dec 18, 2023
Merged
Changes from all commits
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
50 changes: 29 additions & 21 deletions src/PIL/ImageChops.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
# See the README file for information on usage and redistribution.
#

from __future__ import annotations

from . import Image


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

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


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

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


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

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


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


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


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


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

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


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

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


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

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


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

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


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

Expand All @@ -161,7 +163,9 @@ def overlay(image1, image2):
return image1._new(image1.im.chop_overlay(image2.im))


def add(image1, image2, scale=1.0, offset=0):
def add(
image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0
) -> Image.Image:
"""
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 @@ -176,7 +180,9 @@ def add(image1, image2, scale=1.0, offset=0):
return image1._new(image1.im.chop_add(image2.im, scale, offset))


def subtract(image1, image2, scale=1.0, offset=0):
def subtract(
image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0
) -> Image.Image:
"""
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 @@ -191,7 +197,7 @@ def subtract(image1, image2, scale=1.0, offset=0):
return image1._new(image1.im.chop_subtract(image2.im, scale, offset))


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

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


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

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


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

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


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

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


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

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


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

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


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

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


def offset(image, xoffset, yoffset=None):
def offset(image: Image.Image, xoffset: int, yoffset: int | None = None) -> Image.Image:
"""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