[F] Fix RGB to 8bit conversion

This commit is contained in:
Azalea (on HyDEV-Daisy) 2022-04-10 22:43:34 -04:00
parent 5d08179cea
commit 39e14aec90
4 changed files with 51 additions and 13 deletions

View file

@ -1,5 +1,7 @@
import colorsys
from typing import NamedTuple
from typing import NamedTuple, Literal
AnsiMode = Literal['default', 'ansi', '8bit', 'rgb']
def redistribute_rgb(r: int, g: int, b: int) -> tuple[int, int, int]:
@ -69,26 +71,27 @@ class RGB(NamedTuple):
:return: ANSI 256 escape code like \033[38;5;206m'
"""
r, g, b = self
r, g, b = self.r, self.g, self.b
gray_possible = True
gray = False
sep = 42.5
while True:
while gray_possible:
if r < sep or g < sep or b < sep:
gray = r < sep and g < sep and b < sep
break
gray_possible = False
sep += 42.5
if gray:
color = 232 + (r + g + b) / 33
else:
color = 16 + (r / 256 * 6) * 36 + (g / 256 * 6) * 6 + (b / 256 * 6)
color = 16 + int(r / 256. * 6) * 36 + int(g / 256. * 6) * 6 + int(b / 256. * 6)
c = '38' if foreground else '48'
return f'\033[{c};5;{int(color)}m'
def to_ansi_16(self) -> str:
def to_ansi_16(self, foreground: bool = True) -> str:
"""
Convert RGB to ANSI 16 Color Escape Code
@ -96,6 +99,14 @@ class RGB(NamedTuple):
"""
raise NotImplementedError()
def to_ansi(self, mode: AnsiMode, foreground: bool = True):
if mode == 'rgb':
return self.to_ansi_rgb(foreground)
if mode == '8bit':
return self.to_ansi_8bit(foreground)
if mode == 'ansi':
return self.to_ansi_16(foreground)
def lighten(self, multiplier: float) -> 'RGB':
"""
Lighten the color by a multiplier

View file

@ -8,6 +8,7 @@ from typing import Literal, Iterable
from hypy_utils import printc, json_stringify, color
from .color_util import AnsiMode
from .neofetch_util import run_neofetch
from .presets import PRESETS, ColorProfile
@ -18,7 +19,7 @@ CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
@dataclass
class Config:
preset: str
mode: Literal['default', 'ansi', '8bit', 'rgb']
mode: AnsiMode
def save(self):
CONFIG_PATH.write_text(json_stringify(self), 'utf-8')
@ -95,7 +96,7 @@ def create_config() -> Config:
# Select color system
# TODO: Demo of each color system
color_system = literal_input('Which &acolor &bsystem &rdo you want to use?',
['ansi', '8bit', 'rgb'], 'rgb')
['8bit', 'rgb'], 'rgb')
# Print preset
print('Available presets:\n')
@ -135,7 +136,7 @@ def run():
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('-m', '--mode', help=f'Color mode', choices=['ansi', '8bit', 'rgb'])
parser.add_argument('-m', '--mode', help=f'Color mode', choices=['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)
@ -163,4 +164,4 @@ def run():
preset = ColorProfile([c.set_light(args.light) for c in preset.colors])
# Run
run_neofetch(preset)
run_neofetch(preset, config.mode)

View file

@ -6,6 +6,7 @@ from tempfile import TemporaryDirectory
import pkg_resources
from .color_util import AnsiMode
from .presets import ColorProfile
@ -27,7 +28,7 @@ def get_distro_ascii() -> str:
return check_output([get_command_path(), "print_ascii"]).decode().strip()
def run_neofetch(preset: ColorProfile):
def run_neofetch(preset: ColorProfile, mode: AnsiMode):
# Get existing ascii
asc = get_distro_ascii()
@ -37,7 +38,7 @@ def run_neofetch(preset: ColorProfile):
# Add new colors
lines = asc.split('\n')
colors = preset.with_length(len(lines))
asc = '\n'.join([colors[i].to_ansi_rgb() + l for i, l in enumerate(lines)])
asc = '\n'.join([colors[i].to_ansi(mode) + l for i, l in enumerate(lines)])
# Write temp file
with TemporaryDirectory() as tmp_dir:

27
test.py
View file

@ -1,4 +1,7 @@
from hypy_utils import printc
from hyfetch.color_util import RGB
from hyfetch.neofetch_util import get_command_path, run_neofetch
from hyfetch.presets import PRESETS
@ -6,10 +9,32 @@ def print_colors_test(colors: list[RGB]):
print(''.join(f'{c.to_ansi_rgb()}#' for c in colors))
if __name__ == '__main__':
def test_preset_length():
p = PRESETS.get('transgender')
print_colors_test(p.with_length(9))
print_colors_test(p.with_length(6))
p = PRESETS.get('nonbinary')
print_colors_test(p.with_length(7))
print_colors_test(p.with_length(6))
def test_command_path():
print(get_command_path())
def test_rgb_8bit_conversion():
for r in range(0, 255, 16):
for g in range(0, 255, 16):
print(RGB(r, g, 0).to_ansi_rgb(False), end=' ')
printc('&r')
print()
for r in range(0, 255, 16):
for g in range(0, 255, 16):
print(RGB(r, g, 0).to_ansi_8bit(False), end=' ')
printc('&r')
print()
if __name__ == '__main__':
test_rgb_8bit_conversion()