[+] Lighten color
This commit is contained in:
parent
d198b3a947
commit
b62cc3f79e
3 changed files with 61 additions and 13 deletions
|
|
@ -1,6 +1,25 @@
|
||||||
|
import colorsys
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
|
||||||
|
def redistribute_rgb(r: int, g: int, b: int) -> tuple[int, int, int]:
|
||||||
|
"""
|
||||||
|
Redistribute RGB after lightening
|
||||||
|
|
||||||
|
Credit: https://stackoverflow.com/a/141943/7346633
|
||||||
|
"""
|
||||||
|
threshold = 255.999
|
||||||
|
m = max(r, g, b)
|
||||||
|
if m <= threshold:
|
||||||
|
return int(r), int(g), int(b)
|
||||||
|
total = r + g + b
|
||||||
|
if total >= 3 * threshold:
|
||||||
|
return int(threshold), int(threshold), int(threshold)
|
||||||
|
x = (3 * threshold - total) / (3 * m - total)
|
||||||
|
gray = threshold - x * m
|
||||||
|
return int(gray + x * r), int(gray + x * g), int(gray + x * b)
|
||||||
|
|
||||||
|
|
||||||
class RGB(NamedTuple):
|
class RGB(NamedTuple):
|
||||||
r: int
|
r: int
|
||||||
g: int
|
g: int
|
||||||
|
|
@ -59,3 +78,22 @@ class RGB(NamedTuple):
|
||||||
:return: ANSI 16 escape code
|
:return: ANSI 16 escape code
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def lighten(self, multiplier: float) -> 'RGB':
|
||||||
|
"""
|
||||||
|
Lighten the color by a multiplier
|
||||||
|
|
||||||
|
:param multiplier: Multiplier
|
||||||
|
:return: Lightened color (original isn't modified)
|
||||||
|
"""
|
||||||
|
return RGB(*redistribute_rgb(*[v * multiplier for v in self]))
|
||||||
|
|
||||||
|
def set_light(self, light: int) -> 'RGB':
|
||||||
|
"""
|
||||||
|
Set HSL lightness value
|
||||||
|
|
||||||
|
:param light: Lightness value
|
||||||
|
:return: New color (original isn't modified)
|
||||||
|
"""
|
||||||
|
h, l, s = colorsys.rgb_to_hls(*[v / 255.0 for v in self])
|
||||||
|
return RGB(*[round(v * 255.0) for v in colorsys.hls_to_rgb(h, light, s)])
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ from typing import Literal, Iterable
|
||||||
from hypy_utils import printc, json_stringify, color
|
from hypy_utils import printc, json_stringify, color
|
||||||
|
|
||||||
from .neofetch_util import run_neofetch
|
from .neofetch_util import run_neofetch
|
||||||
from .presets import PRESETS
|
from .presets import PRESETS, ColorProfile
|
||||||
|
|
||||||
|
|
||||||
CONFIG_PATH = Path.home() / '.config/hyfetch.json'
|
CONFIG_PATH = Path.home() / '.config/hyfetch.json'
|
||||||
CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
|
CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
|
||||||
|
|
@ -130,6 +129,8 @@ def run():
|
||||||
parser.add_argument('-c', '--config', action='store_true', help=color(f'Configure {hyfetch}'))
|
parser.add_argument('-c', '--config', action='store_true', help=color(f'Configure {hyfetch}'))
|
||||||
parser.add_argument('-p', '--preset', help=f'Use preset', choices=PRESETS.keys())
|
parser.add_argument('-p', '--preset', help=f'Use preset', choices=PRESETS.keys())
|
||||||
parser.add_argument('-m', '--mode', help=f'Color mode', choices=['ansi', '8bit', 'rgb'])
|
parser.add_argument('-m', '--mode', help=f'Color mode', choices=['ansi', '8bit', 'rgb'])
|
||||||
|
parser.add_argument('--c-scale', dest='scale', help=f'Lighten colors by a multiplier', type=float)
|
||||||
|
parser.add_argument('--c-set-l', dest='light', help=f'Set lightness value of the colors', type=float)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
@ -146,5 +147,13 @@ def run():
|
||||||
if args.mode:
|
if args.mode:
|
||||||
config.mode = args.mode
|
config.mode = args.mode
|
||||||
|
|
||||||
|
preset = PRESETS.get(config.preset)
|
||||||
|
|
||||||
|
# Lighten
|
||||||
|
if args.scale:
|
||||||
|
preset = ColorProfile([c.lighten(args.scale) for c in preset.colors])
|
||||||
|
if args.light:
|
||||||
|
preset = ColorProfile([c.set_light(args.light) for c in preset.colors])
|
||||||
|
|
||||||
# Run
|
# Run
|
||||||
run_neofetch(PRESETS.get(config.preset))
|
run_neofetch(preset)
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,23 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
from .color_util import RGB
|
from .color_util import RGB
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ColorProfile:
|
class ColorProfile:
|
||||||
colors: list[str]
|
raw: list[str]
|
||||||
|
colors: list[RGB]
|
||||||
spacing: Literal['equal', 'weighted'] = 'equal'
|
spacing: Literal['equal', 'weighted'] = 'equal'
|
||||||
|
|
||||||
def decode(self) -> list[RGB]:
|
def __init__(self, colors: list[str] | list[RGB]):
|
||||||
"""
|
if isinstance(colors[0], str):
|
||||||
Decode to a list of RGBs
|
self.raw = colors
|
||||||
|
self.colors = [RGB.from_hex(c) for c in colors]
|
||||||
|
else:
|
||||||
|
self.colors = colors
|
||||||
|
|
||||||
:return: List of RGBs
|
|
||||||
"""
|
|
||||||
return [RGB.from_hex(c) for c in self.colors]
|
|
||||||
|
|
||||||
def with_weights(self, weights: list[int]) -> list[RGB]:
|
def with_weights(self, weights: list[int]) -> list[RGB]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -24,8 +26,7 @@ class ColorProfile:
|
||||||
:param weights: Weights of each color (weights[i] = how many times color[i] appears)
|
:param weights: Weights of each color (weights[i] = how many times color[i] appears)
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
colors = self.decode()
|
return [c for i, w in enumerate(weights) for c in [self.colors[i]] * w]
|
||||||
return [c for i, w in enumerate(weights) for c in [colors[i]] * w]
|
|
||||||
|
|
||||||
def with_length(self, length: int) -> list[RGB]:
|
def with_length(self, length: int) -> list[RGB]:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue