[+] Create color scale without numpy
This commit is contained in:
parent
8d3a3cc7f0
commit
2a0e05e228
2 changed files with 97 additions and 21 deletions
|
@ -1,66 +1,71 @@
|
||||||
|
"""
|
||||||
|
This version of color_scale is a special version made without numpy dependency. The numpy version
|
||||||
|
would be faster, but numpy is 11 MB large. In comparison, hyfetch 1.0.7 is only 105 kB, so it's not
|
||||||
|
a good idea to depend on numpy.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
from numpy import ndarray
|
|
||||||
|
|
||||||
from .color_util import RGB
|
from .color_util import RGB
|
||||||
|
|
||||||
|
|
||||||
def create_gradient_hex(colors: list[str], resolution: int = 300) -> ndarray:
|
def create_gradient_hex(colors: list[str], resolution: int = 300) -> list[RGB]:
|
||||||
"""
|
"""
|
||||||
Create gradient array from hex
|
Create gradient array from hex
|
||||||
"""
|
"""
|
||||||
colors = np.array([RGB.from_hex(s) for s in colors])
|
colors = [RGB.from_hex(s) for s in colors]
|
||||||
return create_gradient(colors, resolution)
|
return create_gradient(colors, resolution)
|
||||||
|
|
||||||
|
|
||||||
def create_gradient(colors: ndarray, resolution: int) -> ndarray:
|
def create_gradient(colors: list[RGB], resolution: int) -> list[RGB]:
|
||||||
"""
|
"""
|
||||||
Create gradient 2d array.
|
Create gradient array
|
||||||
|
|
||||||
Usage: arr[ratio / len(arr), :] = Scaled gradient color at that point
|
Usage: arr[ratio / len(arr)] = Scaled gradient color at that point
|
||||||
"""
|
"""
|
||||||
result = np.zeros((resolution * (len(colors) - 1), 3), dtype='uint8')
|
result = []
|
||||||
|
|
||||||
# Create gradient mapping
|
# Create gradient mapping
|
||||||
for i in range(len(colors) - 1):
|
for i in range(len(colors) - 1):
|
||||||
c1 = colors[i, :]
|
c1 = colors[i]
|
||||||
c2 = colors[i + 1, :]
|
c2 = colors[i + 1]
|
||||||
bi = i * resolution
|
bi = i * resolution
|
||||||
|
|
||||||
for r in range(resolution):
|
for ri in range(resolution):
|
||||||
ratio = r / resolution
|
ratio = ri / resolution
|
||||||
result[bi + r, :] = c2 * ratio + c1 * (1 - ratio)
|
r = int(c2.r * ratio + c1.r * (1 - ratio))
|
||||||
|
g = int(c2.g * ratio + c1.g * (1 - ratio))
|
||||||
|
b = int(c2.b * ratio + c1.b * (1 - ratio))
|
||||||
|
result.append(RGB(r, g, b))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_raw(gradient: ndarray, ratio: float) -> ndarray:
|
def get_raw(gradient: list[RGB], ratio: float) -> RGB:
|
||||||
"""
|
"""
|
||||||
:param gradient: Gradient array (2d)
|
:param gradient: Gradient array (2d)
|
||||||
:param ratio: Between 0-1
|
:param ratio: Between 0-1
|
||||||
:return: RGB subarray (1d, has 3 values)
|
:return: RGB subarray (1d, has 3 values)
|
||||||
"""
|
"""
|
||||||
if ratio == 1:
|
if ratio == 1:
|
||||||
return gradient[-1, :]
|
return gradient[-1]
|
||||||
|
|
||||||
i = int(ratio * len(gradient))
|
i = int(ratio * len(gradient))
|
||||||
return gradient[i, :]
|
return gradient[i]
|
||||||
|
|
||||||
|
|
||||||
class Scale:
|
class Scale:
|
||||||
colors: ndarray
|
colors: list[RGB]
|
||||||
rgb: ndarray
|
rgb: list[RGB]
|
||||||
|
|
||||||
def __init__(self, scale: list[str], resolution: int = 300):
|
def __init__(self, scale: list[str], resolution: int = 300):
|
||||||
self.colors = np.array([RGB.from_hex(s) for s in scale])
|
self.colors = [RGB.from_hex(s) for s in scale]
|
||||||
self.rgb = create_gradient(self.colors, resolution)
|
self.rgb = create_gradient(self.colors, resolution)
|
||||||
|
|
||||||
def __call__(self, ratio: float) -> RGB:
|
def __call__(self, ratio: float) -> RGB:
|
||||||
"""
|
"""
|
||||||
:param ratio: Between 0-1
|
:param ratio: Between 0-1
|
||||||
"""
|
"""
|
||||||
return RGB(*get_raw(self.rgb, ratio))
|
return get_raw(self.rgb, ratio)
|
||||||
|
|
||||||
|
|
||||||
def test_color_scale():
|
def test_color_scale():
|
||||||
|
|
71
hyfetch/color_scale_numpy.py
Normal file
71
hyfetch/color_scale_numpy.py
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from numpy import ndarray
|
||||||
|
|
||||||
|
from .color_util import RGB
|
||||||
|
|
||||||
|
|
||||||
|
def create_gradient_hex(colors: list[str], resolution: int = 300) -> ndarray:
|
||||||
|
"""
|
||||||
|
Create gradient array from hex
|
||||||
|
"""
|
||||||
|
colors = np.array([RGB.from_hex(s) for s in colors])
|
||||||
|
return create_gradient(colors, resolution)
|
||||||
|
|
||||||
|
|
||||||
|
def create_gradient(colors: ndarray, resolution: int) -> ndarray:
|
||||||
|
"""
|
||||||
|
Create gradient 2d array.
|
||||||
|
|
||||||
|
Usage: arr[ratio / len(arr), :] = Scaled gradient color at that point
|
||||||
|
"""
|
||||||
|
result = np.zeros((resolution * (len(colors) - 1), 3), dtype='uint8')
|
||||||
|
|
||||||
|
# Create gradient mapping
|
||||||
|
for i in range(len(colors) - 1):
|
||||||
|
c1 = colors[i, :]
|
||||||
|
c2 = colors[i + 1, :]
|
||||||
|
bi = i * resolution
|
||||||
|
|
||||||
|
for r in range(resolution):
|
||||||
|
ratio = r / resolution
|
||||||
|
result[bi + r, :] = c2 * ratio + c1 * (1 - ratio)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def get_raw(gradient: ndarray, ratio: float) -> ndarray:
|
||||||
|
"""
|
||||||
|
:param gradient: Gradient array (2d)
|
||||||
|
:param ratio: Between 0-1
|
||||||
|
:return: RGB subarray (1d, has 3 values)
|
||||||
|
"""
|
||||||
|
if ratio == 1:
|
||||||
|
return gradient[-1, :]
|
||||||
|
|
||||||
|
i = int(ratio * len(gradient))
|
||||||
|
return gradient[i, :]
|
||||||
|
|
||||||
|
|
||||||
|
class Scale:
|
||||||
|
colors: ndarray
|
||||||
|
rgb: ndarray
|
||||||
|
|
||||||
|
def __init__(self, scale: list[str], resolution: int = 300):
|
||||||
|
self.colors = np.array([RGB.from_hex(s) for s in scale])
|
||||||
|
self.rgb = create_gradient(self.colors, resolution)
|
||||||
|
|
||||||
|
def __call__(self, ratio: float) -> RGB:
|
||||||
|
"""
|
||||||
|
:param ratio: Between 0-1
|
||||||
|
"""
|
||||||
|
return RGB(*get_raw(self.rgb, ratio))
|
||||||
|
|
||||||
|
|
||||||
|
def test_color_scale():
|
||||||
|
scale = Scale(['#232323', '#4F1879', '#B43A78', '#F98766', '#FCFAC0'])
|
||||||
|
|
||||||
|
colors = 100
|
||||||
|
for i in range(colors + 1):
|
||||||
|
print(scale(i / colors).to_ansi_rgb(False), end=' ')
|
Loading…
Reference in a new issue