Skip to content

Commit

Permalink
Merge pull request #8115 from radarhere/type_hints_imagecolor
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk committed Jun 8, 2024
2 parents 5e0fe8f + 14a3265 commit cd125c3
Showing 1 changed file with 28 additions and 25 deletions.
53 changes: 28 additions & 25 deletions src/PIL/ImageColor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@


@lru_cache
def getrgb(color):
def getrgb(color: str) -> tuple[int, int, int] | tuple[int, int, int, int]:
"""
Convert a color string to an RGB or RGBA tuple. If the string cannot be
parsed, this function raises a :py:exc:`ValueError` exception.
Expand All @@ -44,8 +44,10 @@ def getrgb(color):
if rgb:
if isinstance(rgb, tuple):
return rgb
colormap[color] = rgb = getrgb(rgb)
return rgb
rgb_tuple = getrgb(rgb)
assert len(rgb_tuple) == 3
colormap[color] = rgb_tuple
return rgb_tuple

# check for known string formats
if re.match("#[a-f0-9]{3}$", color):
Expand Down Expand Up @@ -88,15 +90,15 @@ def getrgb(color):
if m:
from colorsys import hls_to_rgb

rgb = hls_to_rgb(
rgb_floats = hls_to_rgb(
float(m.group(1)) / 360.0,
float(m.group(3)) / 100.0,
float(m.group(2)) / 100.0,
)
return (
int(rgb[0] * 255 + 0.5),
int(rgb[1] * 255 + 0.5),
int(rgb[2] * 255 + 0.5),
int(rgb_floats[0] * 255 + 0.5),
int(rgb_floats[1] * 255 + 0.5),
int(rgb_floats[2] * 255 + 0.5),
)

m = re.match(
Expand All @@ -105,15 +107,15 @@ def getrgb(color):
if m:
from colorsys import hsv_to_rgb

rgb = hsv_to_rgb(
rgb_floats = hsv_to_rgb(
float(m.group(1)) / 360.0,
float(m.group(2)) / 100.0,
float(m.group(3)) / 100.0,
)
return (
int(rgb[0] * 255 + 0.5),
int(rgb[1] * 255 + 0.5),
int(rgb[2] * 255 + 0.5),
int(rgb_floats[0] * 255 + 0.5),
int(rgb_floats[1] * 255 + 0.5),
int(rgb_floats[2] * 255 + 0.5),
)

m = re.match(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color)
Expand All @@ -124,7 +126,7 @@ def getrgb(color):


@lru_cache
def getcolor(color, mode: str) -> tuple[int, ...]:
def getcolor(color: str, mode: str) -> int | tuple[int, ...]:
"""
Same as :py:func:`~PIL.ImageColor.getrgb` for most modes. However, if
``mode`` is HSV, converts the RGB value to a HSV value, or if ``mode`` is
Expand All @@ -136,33 +138,34 @@ def getcolor(color, mode: str) -> tuple[int, ...]:
:param color: A color string
:param mode: Convert result to this mode
:return: ``(graylevel[, alpha]) or (red, green, blue[, alpha])``
:return: ``graylevel, (graylevel, alpha) or (red, green, blue[, alpha])``
"""
# same as getrgb, but converts the result to the given mode
color, alpha = getrgb(color), 255
if len(color) == 4:
color, alpha = color[:3], color[3]
rgb, alpha = getrgb(color), 255
if len(rgb) == 4:
alpha = rgb[3]
rgb = rgb[:3]

if mode == "HSV":
from colorsys import rgb_to_hsv

r, g, b = color
r, g, b = rgb
h, s, v = rgb_to_hsv(r / 255, g / 255, b / 255)
return int(h * 255), int(s * 255), int(v * 255)
elif Image.getmodebase(mode) == "L":
r, g, b = color
r, g, b = rgb
# ITU-R Recommendation 601-2 for nonlinear RGB
# scaled to 24 bits to match the convert's implementation.
color = (r * 19595 + g * 38470 + b * 7471 + 0x8000) >> 16
graylevel = (r * 19595 + g * 38470 + b * 7471 + 0x8000) >> 16
if mode[-1] == "A":
return color, alpha
else:
if mode[-1] == "A":
return color + (alpha,)
return color
return graylevel, alpha
return graylevel
elif mode[-1] == "A":
return rgb + (alpha,)
return rgb


colormap = {
colormap: dict[str, str | tuple[int, int, int]] = {
# X11 colour table from https://drafts.csswg.org/css-color-4/, with
# gray/grey spelling issues fixed. This is a superset of HTML 4.0
# colour names used in CSS 1.
Expand Down

0 comments on commit cd125c3

Please sign in to comment.