convert hsv_to_rgb to faster 16bit fixed point

This commit is contained in:
xs5871 2022-03-24 21:23:53 +00:00 committed by Kyle Brown
parent 24d0587ac6
commit ea19f5bb30

View File

@ -8,10 +8,68 @@ from kmk.keys import make_key
from kmk.kmktime import PeriodicTimer
from kmk.utils import clamp
rgb_config = {}
def hsv_to_rgb(hue, sat, val):
'''
Converts HSV values, and returns a tuple of RGB values
:param hue:
:param sat:
:param val:
:return: (r, g, b)
'''
if sat == 0:
return (val, val, val)
hue = 6 * (hue & 0xFF)
frac = hue & 0xFF
sxt = hue >> 8
base = (0xFF - sat) * val
color = (val * sat * frac) >> 8
val <<= 8
if sxt == 0:
r = val
g = base + color
b = base
elif sxt == 1:
r = val - color
g = val
b = base
elif sxt == 2:
r = base
g = val
b = base + color
elif sxt == 3:
r = base
g = val - color
b = val
elif sxt == 4:
r = base + color
g = base
b = val
elif sxt == 5:
r = val
g = base
b = val - color
return (r >> 8), (g >> 8), (b >> 8)
def hsv_to_rgbw(self, hue, sat, val):
'''
Converts HSV values, and returns a tuple of RGBW values
:param hue:
:param sat:
:param val:
:return: (r, g, b, w)
'''
rgb = hsv_to_rgb(hue, sat, val)
return rgb[0], rgb[1], rgb[2], min(rgb)
class AnimationModes:
OFF = 0
STATIC = 1
@ -31,14 +89,14 @@ class RGB(Extension):
self,
pixel_pin,
num_pixels=0,
val_limit=100,
val_limit=255,
hue_default=0,
sat_default=100,
sat_default=255,
rgb_order=(1, 0, 2), # GRB WS2812
val_default=100,
hue_step=5,
sat_step=5,
val_step=5,
val_default=255,
hue_step=4,
sat_step=13,
val_step=13,
animation_speed=1,
breathe_center=1, # 1.0-2.7
knight_effect_length=3,
@ -175,69 +233,6 @@ class RGB(Extension):
def on_powersave_disable(self, sandbox):
self._do_update()
def hsv_to_rgb(self, hue, sat, val):
'''
Converts HSV values, and returns a tuple of RGB values
:param hue:
:param sat:
:param val:
:return: (r, g, b)
'''
r = 0
g = 0
b = 0
if val > self.val_limit:
val = self.val_limit
if sat == 0:
r = val
g = val
b = val
else:
base = ((100 - sat) * val) / 100
color = (val - base) * ((hue % 60) / 60)
x = int(hue / 60)
if x == 0:
r = val
g = base + color
b = base
elif x == 1:
r = val - color
g = val
b = base
elif x == 2:
r = base
g = val
b = base + color
elif x == 3:
r = base
g = val - color
b = val
elif x == 4:
r = base + color
g = base
b = val
elif x == 5:
r = val
g = base
b = val - color
return int(r), int(g), int(b)
def hsv_to_rgbw(self, hue, sat, val):
'''
Converts HSV values, and returns a tuple of RGBW values
:param hue:
:param sat:
:param val:
:return: (r, g, b, w)
'''
rgb = self.hsv_to_rgb(hue, sat, val)
return rgb[0], rgb[1], rgb[2], min(rgb)
def set_hsv(self, hue, sat, val, index):
'''
Takes HSV values and displays it on a single LED/Neopixel
@ -248,9 +243,9 @@ class RGB(Extension):
'''
if self.pixels:
if self.rgbw:
self.set_rgb(self.hsv_to_rgbw(hue, sat, val), index)
self.set_rgb(hsv_to_rgbw(hue, sat, val), index)
else:
self.set_rgb(self.hsv_to_rgb(hue, sat, val), index)
self.set_rgb(hsv_to_rgb(hue, sat, val), index)
def set_hsv_fill(self, hue, sat, val):
'''
@ -261,9 +256,9 @@ class RGB(Extension):
'''
if self.pixels:
if self.rgbw:
self.set_rgb_fill(self.hsv_to_rgbw(hue, sat, val))
self.set_rgb_fill(hsv_to_rgbw(hue, sat, val))
else:
self.set_rgb_fill(self.hsv_to_rgb(hue, sat, val))
self.set_rgb_fill(hsv_to_rgb(hue, sat, val))
def set_rgb(self, rgb, index):
'''
@ -288,42 +283,42 @@ class RGB(Extension):
def increase_hue(self, step=None):
'''
Increases hue by step amount rolling at 360 and returning to 0
Increases hue by step amount rolling at 256 and returning to 0
:param step:
'''
if step is None:
step = self.hue_step
self.hue = (self.hue + step) % 360
self.hue = (self.hue + step) % 256
if self._check_update():
self._do_update()
def decrease_hue(self, step=None):
'''
Decreases hue by step amount rolling at 0 and returning to 360
Decreases hue by step amount rolling at 0 and returning to 256
:param step:
'''
if step is None:
step = self.hue_step
if (self.hue - step) <= 0:
self.hue = (self.hue + 360 - step) % 360
self.hue = (self.hue + 256 - step) % 256
else:
self.hue = (self.hue - step) % 360
self.hue = (self.hue - step) % 256
if self._check_update():
self._do_update()
def increase_sat(self, step=None):
'''
Increases saturation by step amount stopping at 100
Increases saturation by step amount stopping at 255
:param step:
'''
if step is None:
step = self.sat_step
self.sat = clamp(self.sat + step, 0, 100)
self.sat = clamp(self.sat + step, 0, 255)
if self._check_update():
self._do_update()
@ -336,7 +331,7 @@ class RGB(Extension):
if step is None:
step = self.sat_step
self.sat = clamp(self.sat - step, 0, 100)
self.sat = clamp(self.sat - step, 0, 255)
if self._check_update():
self._do_update()
@ -349,7 +344,7 @@ class RGB(Extension):
if step is None:
step = self.val_step
self.val = clamp(self.val + step, 0, 100)
self.val = clamp(self.val + step, 0, 255)
if self._check_update():
self._do_update()
@ -362,7 +357,7 @@ class RGB(Extension):
if step is None:
step = self.val_step
self.val = clamp(self.val - step, 0, 100)
self.val = clamp(self.val - step, 0, 255)
if self._check_update():
self._do_update()
@ -478,7 +473,7 @@ class RGB(Extension):
self.disable_auto_write = True # Turn off instantly showing
for i in range(0, self.num_pixels):
self.set_hsv(
(self.hue - (i * self.num_pixels)) % 360, self.sat, self.val, i
(self.hue - (i * self.num_pixels)) % 256, self.sat, self.val, i
)
# Show final results