Skip to content
This repository was archived by the owner on Jan 13, 2024. It is now read-only.

Commit 08122f5

Browse files
authored
Merge pull request #14 from DirectiveAthena/v4.2.0_Proposal
V4.2.0 proposal
2 parents a6baa08 + 8ba5942 commit 08122f5

File tree

4 files changed

+173
-1
lines changed

4 files changed

+173
-1
lines changed

Tests/Functions/test_BlendModes.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# ----------------------------------------------------------------------------------------------------------------------
2+
# - Package Imports -
3+
# ----------------------------------------------------------------------------------------------------------------------
4+
# General Packages
5+
from __future__ import annotations
6+
import unittest
7+
8+
# Custom Library
9+
from AthenaColor.Objects.Color.ColorSystem import RGB, RGBA
10+
from AthenaColor.Functions.BlendModes import *
11+
12+
13+
# Custom Packages
14+
15+
# ----------------------------------------------------------------------------------------------------------------------
16+
# - Code -
17+
# ----------------------------------------------------------------------------------------------------------------------
18+
class Functions_BlendModes(unittest.TestCase):
19+
def test_blend_normal(self):
20+
self.assertEqual(
21+
RGBA(255,255,255,255),
22+
blend_normal(RGB(128,128,128), RGB(255,255,255))
23+
)
24+
25+
def test_blend_multiply(self):
26+
self.assertEqual(
27+
RGBA(82, 77, 45,255),
28+
blend_multiply(RGB(246, 231, 134), RGB(85,85,85))
29+
)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
setuptools.setup(
1616
name="AthenaColor",
17-
version="4.1.2",
17+
version="4.2.0",
1818
author="Andreas Sas",
1919
author_email="",
2020
description="Package to support full usage of RGB colors in the Console.",
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# ----------------------------------------------------------------------------------------------------------------------
2+
# - Package Imports -
3+
# ----------------------------------------------------------------------------------------------------------------------
4+
# General Packages
5+
from __future__ import annotations
6+
7+
import math
8+
from typing import Callable
9+
10+
# Custom Library
11+
12+
# Custom Packages
13+
from AthenaColor.Objects.Color.ColorSystem import ColorSystem, RGBA
14+
from AthenaColor.Objects.Color.ColorObjectConversion import to_RGBA
15+
from AthenaColor.Objects.Color.ColorTupleConversion import NormalizeRgba
16+
17+
# ----------------------------------------------------------------------------------------------------------------------
18+
# - Support Code -
19+
# ----------------------------------------------------------------------------------------------------------------------
20+
__all__ = [
21+
"blend_normal", "blend_linearburn", "blend_colordodge", "blend_difference", "blend_lineardodge", "blend_screen",
22+
"blend_darken", "blend_linearlight", "blend_vividlight", "blend_colorburn", "blend_multiply", "blend_lighten",
23+
"blend_overlay", "blend_exclusion", "blend_hardlight", "blend_softlight", "blend_pinlight"
24+
]
25+
26+
# ----------------------------------------------------------------------------------------------------------------------
27+
# - Support Code -
28+
# ----------------------------------------------------------------------------------------------------------------------
29+
def _blend_function(color1:ColorSystem,color2:ColorSystem, formula:Callable) -> RGBA:
30+
color1_tuple = NormalizeRgba(*to_RGBA(color1).export())
31+
color2_tuple = NormalizeRgba(*to_RGBA(color2).export())
32+
33+
# WARNING below values are normalized (aka between 0 and 1)
34+
normalized_outcome = (formula(a, b) for a, b in zip(color1_tuple, color2_tuple))
35+
return RGBA(*(n * 255 for n in normalized_outcome)) # need to de normalize them again
36+
37+
# ----------------------------------------------------------------------------------------------------------------------
38+
# - Code -
39+
# ----------------------------------------------------------------------------------------------------------------------
40+
def blend_normal(color1:ColorSystem, color2:ColorSystem) -> RGBA:
41+
# possible because to_RGBA creates a new object
42+
return to_RGBA(color2)
43+
44+
def blend_darken(color1:ColorSystem, color2:ColorSystem) -> RGBA:
45+
formula = lambda a, b: min(a, b)
46+
return _blend_function(color1,color2,formula)
47+
48+
def blend_multiply(color1:ColorSystem, color2:ColorSystem) -> RGBA:
49+
formula = lambda a,b : a*b
50+
return _blend_function(color1,color2,formula)
51+
52+
def blend_colorburn(color1:ColorSystem, color2:ColorSystem) -> RGBA:
53+
formula = lambda a,b : 1-(1-a)/b
54+
return _blend_function(color1,color2,formula)
55+
56+
def blend_linearburn(color1:ColorSystem, color2:ColorSystem) -> RGBA:
57+
formula = lambda a,b : a+b-1
58+
return _blend_function(color1,color2,formula)
59+
60+
def blend_lighten(color1:ColorSystem, color2:ColorSystem) -> RGBA:
61+
formula = lambda a,b : max(a,b)
62+
return _blend_function(color1,color2,formula)
63+
64+
def blend_screen(color1:ColorSystem, color2:ColorSystem) -> RGBA:
65+
formula = lambda a,b : 1-(1-a)(1-b)
66+
return _blend_function(color1,color2,formula)
67+
68+
def blend_colordodge(color1:ColorSystem, color2:ColorSystem) -> RGBA:
69+
formula = lambda a,b : a/(1-b)
70+
return _blend_function(color1,color2,formula)
71+
72+
def blend_lineardodge(color1:ColorSystem, color2:ColorSystem) -> RGBA:
73+
formula = lambda a,b : a+b
74+
return _blend_function(color1,color2,formula)
75+
76+
def blend_overlay(color1:ColorSystem, color2:ColorSystem) -> RGBA:
77+
def formula(a: float, b: float):
78+
if a < 0.5:
79+
return 1 - 2 * (1 - a) * (1 - b)
80+
else:
81+
return 2 * a * b
82+
83+
return _blend_function(color1,color2,formula)
84+
85+
def blend_softlight(color1:ColorSystem, color2:ColorSystem) -> RGBA:
86+
def formula(a: float, b: float):
87+
if a <= 0.25:
88+
g_w3c = ((16*a-12)*a+4)*a
89+
else:
90+
g_w3c = math.sqrt(a)
91+
92+
if b <=0.5:
93+
return a-(1-2*b)*a*(1-a)
94+
else:
95+
return a+(2*b-1)*(g_w3c-a)
96+
97+
return _blend_function(color1,color2,formula)
98+
99+
def blend_hardlight(color1:ColorSystem, color2:ColorSystem) -> RGBA:
100+
def formula(a: float, b: float):
101+
if b < 0.5:
102+
return a*(2*b)
103+
else:
104+
return 1-(1-a)*(1-2*(b-0.5))
105+
106+
return _blend_function(color1,color2,formula)
107+
108+
def blend_vividlight(color1:ColorSystem, color2:ColorSystem) -> RGBA:
109+
def formula(a: float, b: float):
110+
if b < 0.5:
111+
return 1-(1-a)/(2*b)
112+
else:
113+
return a/(1-2*(b-.5))
114+
115+
return _blend_function(color1,color2,formula)
116+
117+
def blend_linearlight(color1:ColorSystem, color2:ColorSystem) -> RGBA:
118+
def formula(a: float, b: float):
119+
if b < 0.5:
120+
return a+2*b-1
121+
else:
122+
return a+2*(b-.5)
123+
124+
return _blend_function(color1,color2,formula)
125+
126+
def blend_pinlight(color1:ColorSystem, color2:ColorSystem) -> RGBA:
127+
def formula(a: float, b: float):
128+
if b < 0.5:
129+
return min(a,2*b)
130+
else:
131+
return max(a,2*(b-.5))
132+
133+
return _blend_function(color1,color2,formula)
134+
135+
def blend_difference(color1:ColorSystem, color2:ColorSystem) -> RGBA:
136+
formula = lambda a,b : abs(a-b)
137+
return _blend_function(color1,color2,formula)
138+
139+
def blend_exclusion(color1:ColorSystem, color2:ColorSystem) -> RGBA:
140+
formula = lambda a,b : 0.5-2*(a-.5)*(2-.5)
141+
return _blend_function(color1,color2,formula)

src/AthenaColor/Objects/Color/ColorTupleConversion.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
# ----------------------------------------------------------------------------------------------------------------------
3131
def NormalizeRgb(r:int,g:int,b:int) -> Tuple[float, ...]:
3232
return r/255,g/255,b/255
33+
def NormalizeRgba(r:int,g:int,b:int,a:int) -> Tuple[float, ...]:
34+
return r/255,g/255,b/255, a/255
3335

3436
numbers = (int,float)
3537

0 commit comments

Comments
 (0)