diff --git a/src/colordetect/color_detect.py b/src/colordetect/color_detect.py index ef1a98b..a51fce8 100644 --- a/src/colordetect/color_detect.py +++ b/src/colordetect/color_detect.py @@ -247,10 +247,16 @@ def _format_color(self, rgb_value, color_format: str): ValueError ): # Calculate distances between rgb value and CSS3 rgb colours to determine the closest distances = {} - for k, v in webcolors.CSS3_HEX_TO_NAMES.items(): - r1, g1, b1 = webcolors.hex_to_rgb(k) + if hasattr(webcolors, "names"): + color_names = webcolors.names(spec=webcolors.CSS3) + else: + color_names = webcolors.CSS3_NAMES_TO_HEX + + for color_name in color_names: + r1, g1, b1 = webcolors.name_to_rgb(color_name, spec=webcolors.CSS3) distances[((r0 - r1) ** 2 + (g0 - g1) ** 2 + (b0 - b1) ** 2)] = ( - v # Ignore sqrt as it has no significant effect + webcolors.rgb_to_name((r1, g1, b1), spec=webcolors.CSS3) + # Ignore sqrt as it has no significant effect ) nearest = distances[min(distances.keys())] return nearest diff --git a/tests/test_unit.py b/tests/test_unit.py index 5640ed4..de80c6f 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -6,6 +6,8 @@ import os from pathlib import Path +import cv2 +import numpy as np import pytest from colordetect import ColorDetect, VideoColor, col_share @@ -38,6 +40,17 @@ def test_get_color_count_has_correct_color_and_count(image): assert user_image.get_color_count(color_count=1) == {"white": 100.0} +def test_get_color_count_uses_nearest_human_readable_color(tmp_path): + """Ensure colors without exact CSS3 names use the nearest name.""" + image_path = tmp_path / "swatch.png" + pixels = np.full((20, 20, 3), (30, 20, 10), dtype=np.uint8) + assert cv2.imwrite(str(image_path), pixels) + + assert ColorDetect(str(image_path)).get_color_count(color_count=1) == { + "black": 100.0 + } + + def test_image_saving(datadir, image): """ Ensure the image is saved and arguments parsed are valid