Skip to content

Commit ad4d779

Browse files
committed
Update ColorAide version to one that uses exact CSS HWB algorithm
1 parent 9ab60e5 commit ad4d779

File tree

6 files changed

+39
-32
lines changed

6 files changed

+39
-32
lines changed

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# ColorHelper
22

3+
## 6.3.1
4+
5+
- **FIX**: Update to ColorAide 2.9.1 which uses the exact CSS HWB
6+
algorithm instead of the HSV -> HWB algorithm.
7+
38
## 6.3.0
49

510
- **NEW**: Upgrade to ColorAide 2.9.

lib/coloraide/__meta__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,5 @@ def parse_version(ver: str) -> Version:
192192
return Version(major, minor, micro, release, pre, post, dev)
193193

194194

195-
__version_info__ = Version(2, 9, 0, "final")
195+
__version_info__ = Version(2, 9, 1, "final", post=1)
196196
__version__ = __version_info__._get_canonical()

lib/coloraide/average.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88
from .color import Color
99

1010

11-
def average(create: Type['Color'], colors: Iterable[ColorInput], space: str, premultiplied: bool = True) -> 'Color':
11+
def average(
12+
create: Type['Color'],
13+
colors: Iterable[ColorInput],
14+
space: str,
15+
premultiplied: bool = True,
16+
powerless: bool = False
17+
) -> 'Color':
1218
"""Average a list of colors together."""
1319

1420
obj = create(space, [])
@@ -29,7 +35,7 @@ def average(create: Type['Color'], colors: Iterable[ColorInput], space: str, pre
2935
for c in colors:
3036
obj.update(c)
3137
# If cylindrical color is achromatic, ensure hue is undefined
32-
if hue_index >= 0 and not math.isnan(obj[hue_index]) and obj.is_achromatic():
38+
if powerless and hue_index >= 0 and not math.isnan(obj[hue_index]) and obj.is_achromatic():
3339
obj[hue_index] = alg.nan
3440
coords = obj[:]
3541
alpha = coords[-1]

lib/coloraide/color.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,7 @@ def average(
10691069
space: Optional[str] = None,
10701070
out_space: Optional[str] = None,
10711071
premultiplied: bool = True,
1072+
powerless: Optional[bool] = None,
10721073
**kwargs: Any
10731074
) -> 'Color':
10741075
"""Average the colors."""
@@ -1079,7 +1080,13 @@ def average(
10791080
if out_space is None:
10801081
out_space = space
10811082

1082-
return average.average(cls, colors, space, premultiplied).convert(out_space, in_place=True)
1083+
return average.average(
1084+
cls,
1085+
colors,
1086+
space,
1087+
premultiplied,
1088+
powerless if powerless is not None else cls.POWERLESS,
1089+
).convert(out_space, in_place=True)
10831090

10841091
def filter( # noqa: A003
10851092
self,
Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,30 @@
11
"""HWB class."""
22
from ...spaces import Space, HWBish
3+
from ..hsl import srgb_to_hsl, hsl_to_srgb
34
from ...cat import WHITES
4-
from ... import util
55
from ...channels import Channel, FLG_ANGLE, FLG_OPT_PERCENT
66
from ...types import Vector
77

88

9-
def hwb_to_hsv(hwb: Vector) -> Vector:
10-
"""HWB to HSV."""
9+
def srgb_to_hwb(srgb: Vector) -> Vector:
10+
"""HWB to sRGB."""
1111

12-
h, w, b = hwb
13-
14-
wb = w + b
15-
if wb >= 1:
16-
return [h, 0.0, w / wb]
17-
18-
v = 1 - b
19-
s = 0 if v == 0 else 1 - w / v
20-
return [util.constrain_hue(h), s, v]
12+
return [srgb_to_hsl(srgb)[0], min(srgb), 1 - max(srgb)]
2113

2214

23-
def hsv_to_hwb(hsv: Vector) -> Vector:
24-
"""HSV to HWB."""
15+
def hwb_to_srgb(hwb: Vector) -> Vector:
16+
"""HWB to sRGB."""
2517

26-
h, s, v = hsv
27-
return [util.constrain_hue(h), v * (1 - s), 1 - v]
18+
h, w, b = hwb
19+
wb_sum = w + b
20+
wb_factor = 1 - w - b
21+
return [w / wb_sum] * 3 if wb_sum >= 1 else [c * wb_factor + w for c in hsl_to_srgb([h, 1, 0.5])]
2822

2923

3024
class HWB(HWBish, Space):
3125
"""HWB class."""
3226

33-
BASE = "hsv"
27+
BASE = "srgb"
3428
NAME = "hwb"
3529
SERIALIZE = ("--hwb",)
3630
CHANNELS = (
@@ -49,19 +43,14 @@ class HWB(HWBish, Space):
4943
def is_achromatic(self, coords: Vector) -> bool:
5044
"""Check if color is achromatic."""
5145

52-
if (coords[1] + coords[2]) >= (1 - 1e-07):
53-
return True
54-
55-
v = 1 - coords[2]
56-
s = 0 if v == 0 else 1 - coords[1] / v
57-
return abs(s) < 1e-4
46+
return (coords[1] + coords[2]) >= (1 - 1e-07)
5847

5948
def to_base(self, coords: Vector) -> Vector:
60-
"""To HSV from HWB."""
49+
"""To sRGB from HWB."""
6150

62-
return hwb_to_hsv(coords)
51+
return hwb_to_srgb(coords)
6352

6453
def from_base(self, coords: Vector) -> Vector:
65-
"""From HSV to HWB."""
54+
"""From sRGB to HWB."""
6655

67-
return hsv_to_hwb(coords)
56+
return srgb_to_hwb(coords)

support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import webbrowser
66
import re
77

8-
__version__ = "6.3.0"
8+
__version__ = "6.3.1"
99
__pc_name__ = 'ColorHelper'
1010

1111
CSS = '''

0 commit comments

Comments
 (0)