Skip to content

Commit 16385de

Browse files
committed
Updated Hued to version 1.0.7 with 2 new analysis functions.
1 parent 9f41446 commit 16385de

3 files changed

Lines changed: 87 additions & 2 deletions

File tree

hued/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from hued.colors import ColorManager
2-
from hued.analysis import get_temperature, is_neutral, brightness, is_pastel, is_muted, is_vibrant, rgb_to_linear, get_luminance, get_vibrancy, color_contrast, get_text_color_from_background
2+
from hued.analysis import get_temperature, is_neutral, brightness, is_pastel, is_muted, is_vibrant, rgb_to_linear, get_luminance, get_vibrancy, color_contrast, get_text_color_from_background, check_color_quality, simulate_color_blindness
33
from hued.conversions import rgb_to_hex, hex_to_rgb, rgb_to_hsl, hsl_to_rgb, rgb_to_hsv, hsv_to_rgb, rgb_to_cmyk, cmyk_to_rgb, blend_colors, hex_to_cmyk, hex_to_hsl, hex_to_hsv, hsv_to_cmyk, hsv_to_hex, hsv_to_hsl, hsl_to_cmyk, hsl_to_hex, hsl_to_hsv, cmyk_to_hex, cmyk_to_hsl, cmyk_to_hsv, rgb_to_xyz, xyz_to_rgb, xyz_to_cmyk, xyz_to_hex, xyz_to_hsl, xyz_to_hsv, hex_to_xyz, hsl_to_xyz, hsv_to_xyz, cmyk_to_xyz
44
from hued.palettes import ColorPalette

hued/analysis.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,86 @@ def get_text_color_from_background(background_color):
209209
if vibrancy_value < 0.4: # Muted bright colors
210210
return "dark" # Use dark text for readability
211211
else:
212-
return "light" # Use light text for vibrant bright colors
212+
return "light" # Use light text for vibrant bright colors
213+
214+
def check_color_quality(rgb):
215+
"""
216+
Evaluates if a color is of 'good quality' for UI/text usage.
217+
218+
This function simulates a color visibility tester by checking the color's
219+
contrast ratio against standard black and white backgrounds. A color is
220+
considered 'good quality' if it meets the WCAG AA standard (contrast ratio >= 4.5)
221+
against at least one of the backgrounds.
222+
223+
Parameters:
224+
rgb (tuple): A tuple containing the RGB values (r, g, b).
225+
226+
Returns:
227+
dict: A dictionary containing:
228+
- 'contrast_with_black' (float): Contrast ratio with black.
229+
- 'contrast_with_white' (float): Contrast ratio with white.
230+
- 'is_good_quality' (bool): True if legible on black or white.
231+
"""
232+
black = (0, 0, 0)
233+
white = (255, 255, 255)
234+
235+
contrast_black = color_contrast(rgb, black)
236+
contrast_white = color_contrast(rgb, white)
237+
238+
# WCAG AA requires 4.5:1 for normal text
239+
is_good = contrast_black >= 4.5 or contrast_white >= 4.5
240+
241+
return {
242+
"contrast_with_black": round(contrast_black, 2),
243+
"contrast_with_white": round(contrast_white, 2),
244+
"is_good_quality": is_good
245+
}
246+
247+
def simulate_color_blindness(rgb, blindness_type="protanopia", intensity=1.0):
248+
"""
249+
Simulates color blindness on a given RGB color.
250+
251+
Parameters:
252+
rgb (tuple): A tuple containing the RGB values (r, g, b).
253+
blindness_type (str): The type of color blindness to simulate.
254+
Options: 'protanopia', 'deuteranopia', 'tritanopia', 'achromatopsia'.
255+
Default is 'protanopia'.
256+
intensity (float): The intensity of the simulation (0.0 to 1.0).
257+
Default is 1.0 (full simulation).
258+
259+
Returns:
260+
tuple: A tuple representing the simulated RGB values.
261+
"""
262+
if not (0 <= intensity <= 1):
263+
raise ValueError("Intensity must be between 0 and 1.")
264+
265+
blindness_type = blindness_type.lower()
266+
267+
# Matrices for color blindness simulation (approximate for sRGB/Linear)
268+
matrices = {
269+
"protanopia": [[0.567, 0.433, 0.0], [0.558, 0.442, 0.0], [0.0, 0.242, 0.758]],
270+
"deuteranopia": [[0.625, 0.375, 0.0], [0.7, 0.3, 0.0], [0.0, 0.3, 0.7]],
271+
"tritanopia": [[0.95, 0.05, 0.0], [0.0, 0.433, 0.567], [0.0, 0.475, 0.525]],
272+
"achromatopsia": [[0.299, 0.587, 0.114], [0.299, 0.587, 0.114], [0.299, 0.587, 0.114]]
273+
}
274+
275+
if blindness_type not in matrices:
276+
raise ValueError(f"Unknown blindness type: {blindness_type}")
277+
278+
matrix = matrices[blindness_type]
279+
r_lin, g_lin, b_lin = rgb_to_linear(rgb)
280+
281+
r_sim = r_lin * matrix[0][0] + g_lin * matrix[0][1] + b_lin * matrix[0][2]
282+
g_sim = r_lin * matrix[1][0] + g_lin * matrix[1][1] + b_lin * matrix[1][2]
283+
b_sim = r_lin * matrix[2][0] + g_lin * matrix[2][1] + b_lin * matrix[2][2]
284+
285+
# Convert back to sRGB (using simplified gamma 2.2 to match rgb_to_linear)
286+
def lin_to_srgb(c): return c ** (1 / 2.2)
287+
r_final, g_final, b_final = lin_to_srgb(max(0, r_sim)) * 255, lin_to_srgb(max(0, g_sim)) * 255, lin_to_srgb(max(0, b_sim)) * 255
288+
289+
return (
290+
max(0, min(255, int(rgb[0] * (1 - intensity) + r_final * intensity))),
291+
max(0, min(255, int(rgb[1] * (1 - intensity) + g_final * intensity))),
292+
max(0, min(255, int(rgb[2] * (1 - intensity) + b_final * intensity)))
293+
)
294+

readme.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
An open-source Python library for color generation, conversion, and retrieval of common properties, palettes, and color information.
99

10+
### Changes in version 1.0.7:
11+
- 2 new functions in `hued.analysis` for testing color visibility and quality, and simulating color blindness.
12+
1013
### Changes in version 1.0.6:
1114
- New functions under `ColorPalette` to create gradients and to export `ColorPalette` data as a CSV, TXT or JSON file.
1215

0 commit comments

Comments
 (0)