Rgb color enhancements (#391)

* Rgb48Color

* Rgb16Color

* Discord readme
This commit is contained in:
Michael Miller
2020-12-26 09:54:21 -08:00
committed by GitHub
parent f33d78d3dc
commit de32dd9cc8
15 changed files with 940 additions and 134 deletions

View File

@@ -12,6 +12,7 @@ Please read this best practices link before connecting your NeoPixels, it will s
For quick questions and support: For quick questions and support:
* [Try the new Github Discussions](https://github.com/Makuna/NeoPixelBus/discussions) * [Try the new Github Discussions](https://github.com/Makuna/NeoPixelBus/discussions)
* [Discord NeoPixelBus Invitation](https://discord.gg/c6FrysvZyV) or if you are already a member of [Discord Server NeoPixelBus](https://discord.com/channels/789177382221119519/789177382221119521)
* Or jump on Gitter * Or jump on Gitter
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Makuna/NeoPixelBus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Makuna/NeoPixelBus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

View File

@@ -10,6 +10,8 @@ NeoPixelBus KEYWORD1
NeoPixelSegmentBus KEYWORD1 NeoPixelSegmentBus KEYWORD1
RgbwColor KEYWORD1 RgbwColor KEYWORD1
RgbColor KEYWORD1 RgbColor KEYWORD1
Rgb16Color KEYWORD1
Rgb48Color KEYWORD1
HslColor KEYWORD1 HslColor KEYWORD1
HsbColor KEYWORD1 HsbColor KEYWORD1
HtmlColor KEYWORD1 HtmlColor KEYWORD1

View File

@@ -51,9 +51,13 @@ License along with NeoPixel. If not, see
#include "internal/NeoSettings.h" #include "internal/NeoSettings.h"
#include "internal/RgbColor.h" #include "internal/RgbColor.h"
#include "internal/Rgb16Color.h"
#include "internal/Rgb48Color.h"
#include "internal/HslColor.h" #include "internal/HslColor.h"
#include "internal/HsbColor.h" #include "internal/HsbColor.h"
#include "internal/HtmlColor.h" #include "internal/HtmlColor.h"
#include "internal/RgbwColor.h" #include "internal/RgbwColor.h"
#include "internal/SegmentDigit.h" #include "internal/SegmentDigit.h"

View File

@@ -25,22 +25,17 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
#include "RgbColor.h" #include "RgbColor.h"
#include "Rgb48Color.h"
#include "HsbColor.h" #include "HsbColor.h"
void HsbColor::_RgbToHsb(float r, float g, float b, HsbColor* color)
HsbColor::HsbColor(const RgbColor& color)
{ {
// convert colors to float between (0.0 - 1.0)
float r = color.R / 255.0f;
float g = color.G / 255.0f;
float b = color.B / 255.0f;
float max = (r > g && r > b) ? r : (g > b) ? g : b; float max = (r > g && r > b) ? r : (g > b) ? g : b;
float min = (r < g && r < b) ? r : (g < b) ? g : b; float min = (r < g&& r < b) ? r : (g < b) ? g : b;
float d = max - min; float d = max - min;
float h = 0.0; float h = 0.0;
float v = max; float v = max;
float s = (v == 0.0f) ? 0 : (d / v); float s = (v == 0.0f) ? 0 : (d / v);
@@ -62,7 +57,27 @@ HsbColor::HsbColor(const RgbColor& color)
} }
H = h; color->H = h;
S = s; color->S = s;
B = v; color->B = v;
}
HsbColor::HsbColor(const RgbColor& color)
{
// convert colors to float between (0.0 - 1.0)
float r = color.R / 255.0f;
float g = color.G / 255.0f;
float b = color.B / 255.0f;
_RgbToHsb(r, g, b, this);
}
HsbColor::HsbColor(const Rgb48Color& color)
{
// convert colors to float between (0.0 - 1.0)
float r = color.R / 65535.0f;
float g = color.G / 65535.0f;
float b = color.B / 65535.0f;
_RgbToHsb(r, g, b, this);
} }

View File

@@ -48,6 +48,11 @@ struct HsbColor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
HsbColor(const RgbColor& color); HsbColor(const RgbColor& color);
// ------------------------------------------------------------------------
// Construct a HsbColor using Rgb48Color
// ------------------------------------------------------------------------
HsbColor(const Rgb48Color& color);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Construct a HsbColor that will have its values set in latter operations // Construct a HsbColor that will have its values set in latter operations
// CAUTION: The H,S,B members are not initialized and may not be consistent // CAUTION: The H,S,B members are not initialized and may not be consistent
@@ -109,5 +114,8 @@ struct HsbColor
float H; float H;
float S; float S;
float B; float B;
private:
static void _RgbToHsb(float r, float g, float b, HsbColor* color);
}; };

View File

@@ -26,16 +26,11 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
#include "RgbColor.h" #include "RgbColor.h"
#include "Rgb48Color.h"
#include "HslColor.h" #include "HslColor.h"
void HslColor::_RgbToHsl(float r, float g, float b, HslColor* color)
HslColor::HslColor(const RgbColor& color)
{ {
// convert colors to float between (0.0 - 1.0)
float r = color.R / 255.0f;
float g = color.G / 255.0f;
float b = color.B / 255.0f;
float max = (r > g && r > b) ? r : (g > b) ? g : b; float max = (r > g && r > b) ? r : (g > b) ? g : b;
float min = (r < g && r < b) ? r : (g < b) ? g : b; float min = (r < g && r < b) ? r : (g < b) ? g : b;
@@ -66,7 +61,27 @@ HslColor::HslColor(const RgbColor& color)
h /= 6.0f; h /= 6.0f;
} }
H = h; color->H = h;
S = s; color->S = s;
L = l; color->L = l;
}
HslColor::HslColor(const RgbColor& color)
{
// convert colors to float between (0.0 - 1.0)
float r = color.R / 255.0f;
float g = color.G / 255.0f;
float b = color.B / 255.0f;
_RgbToHsl(r, g, b, this);
}
HslColor::HslColor(const Rgb48Color& color)
{
// convert colors to float between (0.0 - 1.0)
float r = color.R / 65535.0f;
float g = color.G / 65535.0f;
float b = color.B / 65535.0f;
_RgbToHsl(r, g, b, this);
} }

View File

@@ -49,6 +49,11 @@ struct HslColor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
HslColor(const RgbColor& color); HslColor(const RgbColor& color);
// ------------------------------------------------------------------------
// Construct a HslColor using Rgb48Color
// ------------------------------------------------------------------------
HslColor(const Rgb48Color& color);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Construct a HslColor that will have its values set in latter operations // Construct a HslColor that will have its values set in latter operations
// CAUTION: The H,S,L members are not initialized and may not be consistent // CAUTION: The H,S,L members are not initialized and may not be consistent
@@ -109,5 +114,9 @@ struct HslColor
float H; float H;
float S; float S;
float L; float L;
private:
static void _RgbToHsl(float r, float g, float b, HslColor* color);
}; };

272
src/internal/Rgb16Color.h Normal file
View File

@@ -0,0 +1,272 @@
/*-------------------------------------------------------------------------
Rgb16Color provides a color object that stores in only 16 bits, aka 565 format
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#include "NeoSettings.h"
#include "RgbColorBase.h"
// ------------------------------------------------------------------------
// Rgb16Color represents a color object that is represented by Red, Green, Blue
// component values stored in a single 16 bit value using 565 model.
// It contains helpful color routines to manipulate the color.
// ------------------------------------------------------------------------
struct Rgb16Color : RgbColorBase
{
typedef NeoRgbCurrentSettings SettingsObject;
// ------------------------------------------------------------------------
// Construct a Rgb16Color using R, G, B values (0-255)
// ------------------------------------------------------------------------
Rgb16Color(uint8_t r, uint8_t g, uint8_t b)
{
setR(r);
setG(g);
setB(b);
};
// ------------------------------------------------------------------------
// Construct a Rgb16Color using a single brightness value (0-255)
// This works well for creating gray tone colors
// (0) = black, (255) = white, (128) = gray
// ------------------------------------------------------------------------
Rgb16Color(uint8_t brightness)
{
setR(brightness);
setG(brightness);
setB(brightness);
};
// ------------------------------------------------------------------------
// Construct a Rgb16Color using HtmlColor
// ------------------------------------------------------------------------
Rgb16Color(const HtmlColor& color)
{
RgbColor converted = color;
setR(converted.R);
setG(converted.G);
setB(converted.B);
};
// ------------------------------------------------------------------------
// Construct a Rgb16Color using HslColor
// ------------------------------------------------------------------------
Rgb16Color(const HslColor& color)
{
RgbColor converted = color;
setR(converted.R);
setG(converted.G);
setB(converted.B);
};
// ------------------------------------------------------------------------
// Construct a Rgb16Color using HsbColor
// ------------------------------------------------------------------------
Rgb16Color(const HsbColor& color)
{
RgbColor converted = color;
setR(converted.R);
setG(converted.G);
setB(converted.B);
};
// ------------------------------------------------------------------------
// Construct a Rgb16Color that will have its values set in latter operations
// CAUTION: The _c members are not initialized and may not be consistent
// ------------------------------------------------------------------------
Rgb16Color()
{
};
// ------------------------------------------------------------------------
// properties
// ------------------------------------------------------------------------
void setR(uint8_t r)
{
_c &= 0x07ff;
_c |= ((r & 0xf8) << 8);
};
uint8_t getR() const
{
return (_c & 0xf800) >> 8;
};
void setG(uint8_t g)
{
_c &= 0xf81f;
_c |= ((g & 0xfe) << 3);
};
uint8_t getG() const
{
return (_c & 0x07e0) >> 3;
};
void setB(uint8_t b)
{
_c &= 0xffe0;
_c |= ((b & 0xf8) >> 3);
};
uint8_t getB() const
{
return (_c & 0x001f) << 3;
};
// ------------------------------------------------------------------------
// Comparison operators
// ------------------------------------------------------------------------
bool operator==(const Rgb16Color& other) const
{
return (_c == other._c);
};
bool operator!=(const Rgb16Color& other) const
{
return !(*this == other);
};
// ------------------------------------------------------------------------
// CalculateBrightness will calculate the overall brightness
// NOTE: This is a simple linear brightness
// ------------------------------------------------------------------------
uint8_t CalculateBrightness() const
{
RgbColor converted = *this;
return converted.CalculateBrightness();
};
// ------------------------------------------------------------------------
// Dim will return a new color that is blended to black with the given ratio
// ratio - (0-255) where 255 will return the original color and 0 will return black
//
// NOTE: This is a simple linear blend
// ------------------------------------------------------------------------
Rgb16Color Dim(uint8_t ratio) const
{
RgbColor converted = *this;
RgbColor result = converted.Dim(ratio);
return Rgb16Color(result.R, result.G, result.B);
};
// ------------------------------------------------------------------------
// Brighten will return a new color that is blended to white with the given ratio
// ratio - (0-255) where 255 will return the original color and 0 will return white
//
// NOTE: This is a simple linear blend
// ------------------------------------------------------------------------
Rgb16Color Brighten(uint8_t ratio) const
{
RgbColor converted = *this;
RgbColor result = converted.Brighten(ratio);
return Rgb16Color(result.R, result.G, result.B);
};
// ------------------------------------------------------------------------
// Darken will adjust the color by the given delta toward black
// NOTE: This is a simple linear change
// delta - (0-255) the amount to dim the color
// ------------------------------------------------------------------------
void Darken(uint8_t delta)
{
RgbColor converted = *this;
converted.Darken(delta);
setR(converted.R);
setG(converted.G);
setB(converted.B);
};
// ------------------------------------------------------------------------
// Lighten will adjust the color by the given delta toward white
// NOTE: This is a simple linear change
// delta - (0-255) the amount to lighten the color
// ------------------------------------------------------------------------
void Lighten(uint8_t delta)
{
RgbColor converted = *this;
converted.Lighten(delta);
setR(converted.R);
setG(converted.G);
setB(converted.B);
};
// ------------------------------------------------------------------------
// LinearBlend between two colors by the amount defined by progress variable
// left - the color to start the blend at
// right - the color to end the blend at
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
// and a value between will blend the color weighted linearly between them
// ------------------------------------------------------------------------
static Rgb16Color LinearBlend(const Rgb16Color& left, const Rgb16Color& right, float progress)
{
RgbColor result = RgbColor::LinearBlend(left, right, progress);
return Rgb16Color(result.R, result.G, result.B);
};
// ------------------------------------------------------------------------
// BilinearBlend between four colors by the amount defined by 2d variable
// c00 - upper left quadrant color
// c01 - upper right quadrant color
// c10 - lower left quadrant color
// c11 - lower right quadrant color
// x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
// y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
// ------------------------------------------------------------------------
static Rgb16Color BilinearBlend(const Rgb16Color& c00,
const Rgb16Color& c01,
const Rgb16Color& c10,
const Rgb16Color& c11,
float x,
float y)
{
RgbColor result = RgbColor::BilinearBlend(c00, c01, c10, c11, x, y);
return Rgb16Color(result.R, result.G, result.B);
};
uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
{
auto total = 0;
total += getR() * settings.RedTenthMilliAmpere / 255;
total += getG() * settings.GreenTenthMilliAmpere / 255;
total += getB() * settings.BlueTenthMilliAmpere / 255;
return total;
};
protected:
uint16_t _c;
};

170
src/internal/Rgb48Color.cpp Normal file
View File

@@ -0,0 +1,170 @@
/*-------------------------------------------------------------------------
Rgb48Color provides a color object that can be directly consumed by NeoPixelBus
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "Rgb48Color.h"
#include "RgbColor.h"
#include "HslColor.h"
#include "HsbColor.h"
#include "HtmlColor.h"
Rgb48Color::Rgb48Color(const HtmlColor& color)
{
uint32_t temp = color.Color;
B = (temp & 0xff);
temp = temp >> 8;
G = (temp & 0xff);
temp = temp >> 8;
R = (temp & 0xff);
};
Rgb48Color::Rgb48Color(const HslColor& color)
{
float r;
float g;
float b;
_HslToRgb(color, &r, &g, &b);
R = (uint16_t)(r * Max);
G = (uint16_t)(g * Max);
B = (uint16_t)(b * Max);
}
Rgb48Color::Rgb48Color(const HsbColor& color)
{
float r;
float g;
float b;
_HsbToRgb(color, &r, &g, &b);
R = (uint16_t)(r * Max);
G = (uint16_t)(g * Max);
B = (uint16_t)(b * Max);
}
uint16_t Rgb48Color::CalculateBrightness() const
{
return (uint16_t)(((uint32_t)R + (uint32_t)G + (uint32_t)B) / 3);
}
Rgb48Color Rgb48Color::Dim(uint16_t ratio) const
{
// specifically avoids float math
return Rgb48Color(_elementDim(R, ratio), _elementDim(G, ratio), _elementDim(B, ratio));
}
Rgb48Color Rgb48Color::Brighten(uint16_t ratio) const
{
// specifically avoids float math
return Rgb48Color(_elementBrighten(R, ratio), _elementBrighten(G, ratio), _elementBrighten(B, ratio));
}
void Rgb48Color::Darken(uint16_t delta)
{
if (R > delta)
{
R -= delta;
}
else
{
R = 0;
}
if (G > delta)
{
G -= delta;
}
else
{
G = 0;
}
if (B > delta)
{
B -= delta;
}
else
{
B = 0;
}
}
void Rgb48Color::Lighten(uint16_t delta)
{
if (R < Max - delta)
{
R += delta;
}
else
{
R = Max;
}
if (G < Max - delta)
{
G += delta;
}
else
{
G = Max;
}
if (B < Max - delta)
{
B += delta;
}
else
{
B = Max;
}
}
Rgb48Color Rgb48Color::LinearBlend(const Rgb48Color& left, const Rgb48Color& right, float progress)
{
return Rgb48Color( left.R + ((right.R - left.R) * progress),
left.G + ((right.G - left.G) * progress),
left.B + ((right.B - left.B) * progress));
}
Rgb48Color Rgb48Color::BilinearBlend(const Rgb48Color& c00,
const Rgb48Color& c01,
const Rgb48Color& c10,
const Rgb48Color& c11,
float x,
float y)
{
float v00 = (1.0f - x) * (1.0f - y);
float v10 = x * (1.0f - y);
float v01 = (1.0f - x) * y;
float v11 = x * y;
return Rgb48Color(
c00.R * v00 + c10.R * v10 + c01.R * v01 + c11.R * v11,
c00.G * v00 + c10.G * v10 + c01.G * v01 + c11.G * v11,
c00.B * v00 + c10.B * v10 + c01.B * v01 + c11.B * v11);
}

210
src/internal/Rgb48Color.h Normal file
View File

@@ -0,0 +1,210 @@
/*-------------------------------------------------------------------------
Rgb48Color provides a color object that contains 16bit color elements
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#include "NeoSettings.h"
#include "RgbColorBase.h"
#include "RgbColor.h"
// ------------------------------------------------------------------------
// Rgb48Color represents a color object that is represented by Red, Green, Blue
// component values. It contains helpful color routines to manipulate the
// color.
// ------------------------------------------------------------------------
struct Rgb48Color : RgbColorBase
{
typedef NeoRgbCurrentSettings SettingsObject;
// ------------------------------------------------------------------------
// Construct a Rgb48Color using R, G, B values (0-65535)
// ------------------------------------------------------------------------
Rgb48Color(uint16_t r, uint16_t g, uint16_t b) :
R(r), G(g), B(b)
{
};
// ------------------------------------------------------------------------
// Construct a Rgb48Color using a single brightness value (0-65535)
// This works well for creating gray tone colors
// (0) = black, (65535) = white, (32768) = gray
// ------------------------------------------------------------------------
Rgb48Color(uint16_t brightness) :
R(brightness), G(brightness), B(brightness)
{
};
// ------------------------------------------------------------------------
// Construct a Rgb48Color using RgbColor
// ------------------------------------------------------------------------
Rgb48Color(const RgbColor& color)
{
R = (color.R == 0) ? 0 : (color.R << 8 | 0xff);
G = (color.G == 0) ? 0 : (color.G << 8 | 0xff);
B = (color.B == 0) ? 0 : (color.B << 8 | 0xff);
}
// ------------------------------------------------------------------------
// Construct a Rgb48Color using HtmlColor
// ------------------------------------------------------------------------
Rgb48Color(const HtmlColor& color);
// ------------------------------------------------------------------------
// Construct a Rgb48Color using HslColor
// ------------------------------------------------------------------------
Rgb48Color(const HslColor& color);
// ------------------------------------------------------------------------
// Construct a Rgb48Color using HsbColor
// ------------------------------------------------------------------------
Rgb48Color(const HsbColor& color);
// ------------------------------------------------------------------------
// Construct a Rgb48Color that will have its values set in latter operations
// CAUTION: The R,G,B members are not initialized and may not be consistent
// ------------------------------------------------------------------------
Rgb48Color()
{
};
// ------------------------------------------------------------------------
// Comparison operators
// ------------------------------------------------------------------------
bool operator==(const Rgb48Color& other) const
{
return (R == other.R && G == other.G && B == other.B);
};
bool operator!=(const Rgb48Color& other) const
{
return !(*this == other);
};
// ------------------------------------------------------------------------
// CalculateBrightness will calculate the overall brightness
// NOTE: This is a simple linear brightness
// ------------------------------------------------------------------------
uint16_t CalculateBrightness() const;
// ------------------------------------------------------------------------
// Dim will return a new color that is blended to black with the given ratio
// ratio - (0-65535) where 65535 will return the original color and 0 will return black
//
// NOTE: This is a simple linear blend
// ------------------------------------------------------------------------
Rgb48Color Dim(uint16_t ratio) const;
// ------------------------------------------------------------------------
// Brighten will return a new color that is blended to white with the given ratio
// ratio - (0-65535) where 65535 will return the original color and 0 will return white
//
// NOTE: This is a simple linear blend
// ------------------------------------------------------------------------
Rgb48Color Brighten(uint16_t ratio) const;
// ------------------------------------------------------------------------
// Darken will adjust the color by the given delta toward black
// NOTE: This is a simple linear change
// delta - (0-65535) the amount to dim the color
// ------------------------------------------------------------------------
void Darken(uint16_t delta);
// ------------------------------------------------------------------------
// Lighten will adjust the color by the given delta toward white
// NOTE: This is a simple linear change
// delta - (0-65535) the amount to lighten the color
// ------------------------------------------------------------------------
void Lighten(uint16_t delta);
// ------------------------------------------------------------------------
// LinearBlend between two colors by the amount defined by progress variable
// left - the color to start the blend at
// right - the color to end the blend at
// progress - (0.0 - 1.0) value where 0 will return left and 1.0 will return right
// and a value between will blend the color weighted linearly between them
// ------------------------------------------------------------------------
static Rgb48Color LinearBlend(const Rgb48Color& left, const Rgb48Color& right, float progress);
// ------------------------------------------------------------------------
// BilinearBlend between four colors by the amount defined by 2d variable
// c00 - upper left quadrant color
// c01 - upper right quadrant color
// c10 - lower left quadrant color
// c11 - lower right quadrant color
// x - unit value (0.0 - 1.0) that defines the blend progress in horizontal space
// y - unit value (0.0 - 1.0) that defines the blend progress in vertical space
// ------------------------------------------------------------------------
static Rgb48Color BilinearBlend(const Rgb48Color& c00,
const Rgb48Color& c01,
const Rgb48Color& c10,
const Rgb48Color& c11,
float x,
float y);
uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings)
{
auto total = 0;
total += R * settings.RedTenthMilliAmpere / Max;
total += G * settings.GreenTenthMilliAmpere / Max;
total += B * settings.BlueTenthMilliAmpere / Max;
return total;
}
// ------------------------------------------------------------------------
// Red, Green, Blue color members (0-65535) where
// (0,0,0) is black and (65535,65535,65535) is white
// ------------------------------------------------------------------------
uint16_t R;
uint16_t G;
uint16_t B;
const static uint16_t Max = 65535;
private:
inline static uint16_t _elementDim(uint16_t value, uint16_t ratio)
{
return (static_cast<uint32_t>(value) * (static_cast<uint32_t>(ratio) + 1)) >> 8;
}
inline static uint16_t _elementBrighten(uint16_t value, uint16_t ratio)
{
uint32_t element = ((static_cast<uint32_t>(value) + 1) << 8) / (static_cast<uint32_t>(ratio) + 1);
if (element > Max)
{
element = Max;
}
else
{
element -= 1;
}
return element;
}
};

View File

@@ -25,27 +25,17 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
#include "RgbColor.h" #include "RgbColor.h"
#include "Rgb16Color.h"
#include "Rgb48Color.h"
#include "HslColor.h" #include "HslColor.h"
#include "HsbColor.h" #include "HsbColor.h"
#include "HtmlColor.h" #include "HtmlColor.h"
static float _CalcColor(float p, float q, float t) RgbColor::RgbColor(const Rgb16Color& color)
{ {
if (t < 0.0f) R = color.getR();
t += 1.0f; G = color.getG();
if (t > 1.0f) B = color.getB();
t -= 1.0f;
if (t < 1.0f / 6.0f)
return p + (q - p) * 6.0f * t;
if (t < 0.5f)
return q;
if (t < 2.0f / 3.0f)
return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f);
return p;
} }
RgbColor::RgbColor(const HtmlColor& color) RgbColor::RgbColor(const HtmlColor& color)
@@ -65,27 +55,11 @@ RgbColor::RgbColor(const HslColor& color)
float g; float g;
float b; float b;
float h = color.H; _HslToRgb(color, &r, &g, &b);
float s = color.S;
float l = color.L;
R = (uint8_t)(r * Max);
if (color.S == 0.0f || color.L == 0.0f) G = (uint8_t)(g * Max);
{ B = (uint8_t)(b * Max);
r = g = b = l; // achromatic or black
}
else
{
float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
float p = 2.0f * l - q;
r = _CalcColor(p, q, h + 1.0f / 3.0f);
g = _CalcColor(p, q, h);
b = _CalcColor(p, q, h - 1.0f / 3.0f);
}
R = (uint8_t)(r * 255.0f);
G = (uint8_t)(g * 255.0f);
B = (uint8_t)(b * 255.0f);
} }
RgbColor::RgbColor(const HsbColor& color) RgbColor::RgbColor(const HsbColor& color)
@@ -94,68 +68,11 @@ RgbColor::RgbColor(const HsbColor& color)
float g; float g;
float b; float b;
float h = color.H; _HsbToRgb(color, &r, &g, &b);
float s = color.S;
float v = color.B;
if (color.S == 0.0f) R = (uint8_t)(r * Max);
{ G = (uint8_t)(g * Max);
r = g = b = v; // achromatic or black B = (uint8_t)(b * Max);
}
else
{
if (h < 0.0f)
{
h += 1.0f;
}
else if (h >= 1.0f)
{
h -= 1.0f;
}
h *= 6.0f;
int i = (int)h;
float f = h - i;
float q = v * (1.0f - s * f);
float p = v * (1.0f - s);
float t = v * (1.0f - s * (1.0f - f));
switch (i)
{
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
break;
}
}
R = (uint8_t)(r * 255.0f);
G = (uint8_t)(g * 255.0f);
B = (uint8_t)(b * 255.0f);
} }
uint8_t RgbColor::CalculateBrightness() const uint8_t RgbColor::CalculateBrightness() const
@@ -207,31 +124,31 @@ void RgbColor::Darken(uint8_t delta)
void RgbColor::Lighten(uint8_t delta) void RgbColor::Lighten(uint8_t delta)
{ {
if (R < 255 - delta) if (R < Max - delta)
{ {
R += delta; R += delta;
} }
else else
{ {
R = 255; R = Max;
} }
if (G < 255 - delta) if (G < Max - delta)
{ {
G += delta; G += delta;
} }
else else
{ {
G = 255; G = Max;
} }
if (B < 255 - delta) if (B < Max - delta)
{ {
B += delta; B += delta;
} }
else else
{ {
B = 255; B = Max;
} }
} }

View File

@@ -27,17 +27,15 @@ License along with NeoPixel. If not, see
#include <Arduino.h> #include <Arduino.h>
#include "NeoSettings.h" #include "NeoSettings.h"
#include "RgbColorBase.h"
struct HslColor;
struct HsbColor;
struct HtmlColor;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// RgbColor represents a color object that is represented by Red, Green, Blue // RgbColor represents a color object that is represented by Red, Green, Blue
// component values. It contains helpful color routines to manipulate the // component values. It contains helpful color routines to manipulate the
// color. // color.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct RgbColor struct RgbColor : RgbColorBase
{ {
typedef NeoRgbCurrentSettings SettingsObject; typedef NeoRgbCurrentSettings SettingsObject;
@@ -59,6 +57,11 @@ struct RgbColor
{ {
}; };
// ------------------------------------------------------------------------
// Construct a RgbColor using Rgb16Color
// ------------------------------------------------------------------------
RgbColor(const Rgb16Color& color);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Construct a RgbColor using HtmlColor // Construct a RgbColor using HtmlColor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -74,6 +77,7 @@ struct RgbColor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
RgbColor(const HsbColor& color); RgbColor(const HsbColor& color);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Construct a RgbColor that will have its values set in latter operations // Construct a RgbColor that will have its values set in latter operations
// CAUTION: The R,G,B members are not initialized and may not be consistent // CAUTION: The R,G,B members are not initialized and may not be consistent
@@ -160,9 +164,9 @@ struct RgbColor
{ {
auto total = 0; auto total = 0;
total += R * settings.RedTenthMilliAmpere / 255; total += R * settings.RedTenthMilliAmpere / Max;
total += G * settings.GreenTenthMilliAmpere / 255; total += G * settings.GreenTenthMilliAmpere / Max;
total += B * settings.BlueTenthMilliAmpere / 255; total += B * settings.BlueTenthMilliAmpere / Max;
return total; return total;
} }
@@ -175,6 +179,8 @@ struct RgbColor
uint8_t G; uint8_t G;
uint8_t B; uint8_t B;
const static uint8_t Max = 255;
private: private:
inline static uint8_t _elementDim(uint8_t value, uint8_t ratio) inline static uint8_t _elementDim(uint8_t value, uint8_t ratio)
{ {
@@ -185,9 +191,9 @@ private:
{ {
uint16_t element = ((static_cast<uint16_t>(value) + 1) << 8) / (static_cast<uint16_t>(ratio) + 1); uint16_t element = ((static_cast<uint16_t>(value) + 1) << 8) / (static_cast<uint16_t>(ratio) + 1);
if (element > 255) if (element > Max)
{ {
element = 255; element = Max;
} }
else else
{ {

View File

@@ -0,0 +1,134 @@
/*-------------------------------------------------------------------------
RgbColorBase provides a RGB color object common support
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include "RgbColorBase.h"
#include "RgbColor.h"
#include "Rgb48Color.h"
#include "HslColor.h"
#include "HsbColor.h"
#include "HtmlColor.h"
float RgbColorBase::_CalcColor(float p, float q, float t)
{
if (t < 0.0f)
t += 1.0f;
if (t > 1.0f)
t -= 1.0f;
if (t < 1.0f / 6.0f)
return p + (q - p) * 6.0f * t;
if (t < 0.5f)
return q;
if (t < 2.0f / 3.0f)
return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f);
return p;
}
void RgbColorBase::_HslToRgb(const HslColor& color, float* r, float* g, float* b)
{
float h = color.H;
float s = color.S;
float l = color.L;
if (color.S == 0.0f || color.L == 0.0f)
{
*r = *g = *b = l; // achromatic or black
}
else
{
float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
float p = 2.0f * l - q;
*r = _CalcColor(p, q, h + 1.0f / 3.0f);
*g = _CalcColor(p, q, h);
*b = _CalcColor(p, q, h - 1.0f / 3.0f);
}
}
void RgbColorBase::_HsbToRgb(const HsbColor& color, float* r, float* g, float* b)
{
float h = color.H;
float s = color.S;
float v = color.B;
if (color.S == 0.0f)
{
*r = *g = *b = v; // achromatic or black
}
else
{
if (h < 0.0f)
{
h += 1.0f;
}
else if (h >= 1.0f)
{
h -= 1.0f;
}
h *= 6.0f;
int i = (int)h;
float f = h - i;
float q = v * (1.0f - s * f);
float p = v * (1.0f - s);
float t = v * (1.0f - s * (1.0f - f));
switch (i)
{
case 0:
*r = v;
*g = t;
*b = p;
break;
case 1:
*r = q;
*g = v;
*b = p;
break;
case 2:
*r = p;
*g = v;
*b = t;
break;
case 3:
*r = p;
*g = q;
*b = v;
break;
case 4:
*r = t;
*g = p;
*b = v;
break;
default:
*r = v;
*g = p;
*b = q;
break;
}
}
}

View File

@@ -0,0 +1,42 @@
/*-------------------------------------------------------------------------
RgbColorBase provides a RGB color object common support
Written by Michael C. Miller.
I invest time and resources providing this open source code,
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
-------------------------------------------------------------------------
This file is part of the Makuna/NeoPixelBus library.
NeoPixelBus is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
NeoPixelBus is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#pragma once
struct HslColor;
struct HsbColor;
struct HtmlColor;
struct Rgb16Color;
struct RgbColorBase
{
protected:
static float _CalcColor(float p, float q, float t);
static void _HslToRgb(const HslColor& color, float* r, float* g, float* b);
static void _HsbToRgb(const HsbColor& color, float* r, float* g, float* b);
};

View File

@@ -25,6 +25,7 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
#include "RgbColor.h" #include "RgbColor.h"
#include "Rgb48Color.h"
#include "HslColor.h" #include "HslColor.h"
#include "HsbColor.h" #include "HsbColor.h"
#include "RgbwColor.h" #include "RgbwColor.h"