From 4409939c418055d17e8c98895fe362659c58cd70 Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Mon, 30 Jan 2023 15:55:35 +0100 Subject: [PATCH] optimize (#6) - major improvement **BGR()** - minor improvement **CMYK()** - extend timing example. - update readme.md - update GitHub actions - update license 2023 --- CHANGELOG.md | 10 +++- Kelvin2RGB.cpp | 21 ++++--- Kelvin2RGB.h | 7 +-- README.md | 51 ++++++++++------- .../Kelvin2RGB_timing/Kelvin2RGB_timing.ino | 57 ++++++++++++++++++- .../Kelvin2RGB_timing/performance_0.1.5.txt | 18 ++++++ .../Kelvin2RGB_timing/performance_0.1.6.txt | 19 +++++++ library.json | 2 +- library.properties | 2 +- 9 files changed, 148 insertions(+), 39 deletions(-) create mode 100644 examples/Kelvin2RGB_timing/performance_0.1.5.txt create mode 100644 examples/Kelvin2RGB_timing/performance_0.1.6.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index d9387e8..32d088c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.1.6] - 2022-11-14 +- major improvement **BGR()** +- minor improvement **CMYK()** +- extend timing example. +- update readme.md +- update GitHub actions +- update license 2023 + + ## [0.1.5] - 2022-11-14 - Add RP2040 support to build-CI. - Add CHANGELOG.md @@ -14,7 +23,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - fix bug in **BGR()** - fix unit test BGR-bug - ## [0.1.4] - 2021-12-20 - update library.json - update license diff --git a/Kelvin2RGB.cpp b/Kelvin2RGB.cpp index db1ebd5..28e413c 100644 --- a/Kelvin2RGB.cpp +++ b/Kelvin2RGB.cpp @@ -1,12 +1,10 @@ // // FILE: Kelvin2RGB.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.5 +// VERSION: 0.1.6 // DATE: 2018-01-31 // PURPOSE: Arduino library for converting temperature to RGB values // URL: https://github.com/RobTillaart/Kelvin2RGB -// -// HISTORY: see changelog.md #include "Kelvin2RGB.h" @@ -169,11 +167,11 @@ uint32_t Kelvin2RGB::RGB() uint16_t Kelvin2RGB::RGB565() { uint16_t val = 0; - val = uint8_t(_red * 32); + val = uint8_t(_red * 32); val <<= 6; val |= uint8_t(_green * 64); val <<= 5; - val |= uint8_t(_blue * 32); + val |= uint8_t(_blue * 32); return val; } @@ -183,10 +181,14 @@ uint32_t Kelvin2RGB::CMYK() float k = _red; if (k < _green) k = _green; if (k < _blue) k = _blue; + + float t1 = k; k = 1 - k; - uint32_t c = 255 * (1 - _red - k) / (1 - k); - uint32_t m = 255 * (1 - _green - k) / (1 - k); - uint32_t y = 255 * (1 - _blue - k) / (1 - k); + float t2 = 255.0 / (1 - k); + + uint32_t c = (t1 - _red ) * t2; + uint32_t m = (t1 - _green) * t2; + uint32_t y = (t1 - _blue ) * t2; return (c << 24) + (m << 16) + (y << 8) + (k * 255); } @@ -194,7 +196,8 @@ uint32_t Kelvin2RGB::CMYK() uint32_t Kelvin2RGB::BGR() { - return round(255 * _blue) * 65536UL + round(255 * _green) * 256UL + round(255 * _red); + return uint8_t(255 * _blue + 0.5) * 65536UL + uint8_t(255 * _green + 0.5) * 256UL + uint8_t(255 * _red + 0.5); + // return round(255 * 65536UL * _blue) + round(255 * 256UL * _green) + round(255 * _red); } diff --git a/Kelvin2RGB.h b/Kelvin2RGB.h index e41b198..977b975 100644 --- a/Kelvin2RGB.h +++ b/Kelvin2RGB.h @@ -2,14 +2,13 @@ // // FILE: Kelvin2RGB.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.5 +// VERSION: 0.1.6 // DATE: 2018-01-31 // PURPOSE: Arduino library for converting temperature to RGB values // URL: https://github.com/RobTillaart/Kelvin2RGB -// -#define KELVIN2RGB_LIB_VERSION (F("0.1.5")) +#define KELVIN2RGB_LIB_VERSION (F("0.1.6")) #include "Arduino.h" @@ -97,5 +96,5 @@ class Kelvin2RGB }; -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/README.md b/README.md index 2940980..6c7df28 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ Arduino library for converting temperature and brightness to RGB values. ## Credentials -This library is based upon an article of Tanner Helland -and a related story by Neil Bartlett -http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ -http://www.zombieprototypes.com/?p=210 -https://en.wikipedia.org/wiki/Color_temperature#Categorizing_different_lighting +This library is based upon an article of Tanner Helland and a related story by Neil Bartlett + +- http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ +- http://www.zombieprototypes.com/?p=210 +- https://en.wikipedia.org/wiki/Color_temperature#Categorizing_different_lighting There are more approximation formulas, some claim to be better, however these are not investigated. On request these can be added. @@ -26,14 +26,14 @@ however these are not investigated. On request these can be added. ## Description The library converts a temperature in Kelvin and a brightness (0..100%) - to 3 numbers red, green and blue. + to three numbers **red**, **green** and **blue**. These numbers are weights can be used to correct a colour image for virtual white temperature. -There are 2 convert functions where the **convert_NB()** is claimed to be +There are two convert functions where the **convert_NB()** is claimed to be the more accurate one. -With the numbers R,G,B calculated one can convert images so they will look -more like taken with candle light, sunrise or sunset etc. +With the numbers **red**, **green** and **blue** calculated one can convert images +so they will look more like taken with candle light, sunrise or sunset etc. **pseudo code** @@ -51,16 +51,20 @@ for each pixel in image } ``` -The numbers can also be used to reduce the blue channel so it has less effect +The numbers can also be used to reduce the blue channel so it has less effect on "getting sleepy". The library uses floats for the R,G and B weights to keep values as accurate as possible. Especially with images with more than 8 bits per channel this is preferred. -That said it is also possible to use this on a 565 image or to adjust color lookup tables. +That said it is also possible to use this on a 565 image or to adjust colour lookup tables. ## Interface +```cpp +#include "Kelvin2RGB.h" +``` + The interface is straightforward: - **Kelvin2RGB()** constructor @@ -85,8 +89,7 @@ red, green, blue should be in 0 .. 1.0 range. brightness should be in 0..100%, D returns a 24 bit RGB value, - **uint32_t RGB()** returns a 24 bit RGB value, 0 .. 16777215 more efficient than 3 floats for communication. -- **uint16_t RGB565()** returns a 16 bit RGB value, -5 bits for red, 6 for green and 5 for blue. +- **uint16_t RGB565()** returns a 16 bit RGB value, 5 bits for red, 6 for green and 5 for blue. - **uint32_t BGR()** returns a 24 bit BGR value, 0 .. 16777215 - **uint32_t CMYK()** returns a 32 bit = 4 byte CMYK value, @@ -98,21 +101,25 @@ See examples ## Future -#### must -- add examples - - CMYK() - - BGR() +#### Must + +#### Should -#### should - define constants like candleLight as parameter. - investigate other formulas. -- investigate timing and performance - investigate usability for RGB led strip. -- investigate **RGB_10_12_10()** -#### could +#### Could + - separate brightness per colour channel to mimic "artificial illumination" (0.2.0 ?) - remove begin() ? -- example Led-strip() +- add examples + - ledstrip + - CMYK() + - BGR() + +#### Wont +- investigate **RGB_10_12_10()** + - nowhere used (not found) diff --git a/examples/Kelvin2RGB_timing/Kelvin2RGB_timing.ino b/examples/Kelvin2RGB_timing/Kelvin2RGB_timing.ino index d428fd8..e54c57c 100644 --- a/examples/Kelvin2RGB_timing/Kelvin2RGB_timing.ino +++ b/examples/Kelvin2RGB_timing/Kelvin2RGB_timing.ino @@ -34,7 +34,10 @@ void loop() void test_timing() { Serial.println(__FUNCTION__); + Serial.print("KELVIN2RGB_LIB_VERSION: "); + Serial.println(KELVIN2RGB_LIB_VERSION); Serial.println(); + delay(100); // volatile to minimize optimization volatile float bright = 100.0; @@ -62,8 +65,60 @@ void test_timing() Serial.println(duration2 * 0.001); Serial.print("ratio:\t"); Serial.println(1.0 * duration1 / duration2, 4); + Serial.println(); + delay(100); + + volatile uint32_t RGB; + start = micros(); + for (int i = 0; i < 1000; i++) + { + RGB = KRGB.RGB(); + } + stop = micros(); + Serial.print("RGB:\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.println(RGB); + delay(100); + + volatile uint32_t CMYK; + start = micros(); + for (int i = 0; i < 1000; i++) + { + CMYK = KRGB.CMYK(); + } + stop = micros(); + Serial.print("CMYK:\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.println(CMYK); + delay(100); + + volatile uint32_t BGR; + start = micros(); + for (int i = 0; i < 1000; i++) + { + BGR = KRGB.BGR(); + } + stop = micros(); + Serial.print("BGR:\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.println(BGR); + delay(100); + + volatile uint16_t RGB565; + start = micros(); + for (int i = 0; i < 1000; i++) + { + RGB565 = KRGB.RGB565(); + } + stop = micros(); + Serial.print("RGB565:\t"); + Serial.print(stop - start); + Serial.print("\t"); + Serial.println(RGB565); } // -- END OF FILE -- - diff --git a/examples/Kelvin2RGB_timing/performance_0.1.5.txt b/examples/Kelvin2RGB_timing/performance_0.1.5.txt new file mode 100644 index 0000000..23ef295 --- /dev/null +++ b/examples/Kelvin2RGB_timing/performance_0.1.5.txt @@ -0,0 +1,18 @@ +IDE 1.8.19 +UNO + +Kelvin2RGB_timing.ino + +test_timing +KELVIN2RGB_LIB_VERSION: 0.1.5 + +TH: 514.05 +NB: 557.81 +ratio: 0.9216 + +RGB: 760 +CMYK: 936 +BGR: 44540 +RGB565: 552 + +done... diff --git a/examples/Kelvin2RGB_timing/performance_0.1.6.txt b/examples/Kelvin2RGB_timing/performance_0.1.6.txt new file mode 100644 index 0000000..451ddd0 --- /dev/null +++ b/examples/Kelvin2RGB_timing/performance_0.1.6.txt @@ -0,0 +1,19 @@ +IDE 1.8.19 +UNO + +Kelvin2RGB_timing.ino + +test_timing +KELVIN2RGB_LIB_VERSION: 0.1.6 + +TH: 514.05 +NB: 557.81 +ratio: 0.9216 + +RGB: 760 16775934 +CMYK: 888 327680 +BGR: 816 16710399 +RGB565: 544 2015 + +done... + diff --git a/library.json b/library.json index 3514cff..af78219 100644 --- a/library.json +++ b/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/Kelvin2RGB.git" }, - "version": "0.1.5", + "version": "0.1.6", "license": "MIT", "frameworks": "*", "platforms": "*", diff --git a/library.properties b/library.properties index b194dec..86f7298 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Kelvin2RGB -version=0.1.5 +version=0.1.6 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for converting temperature to RGB values