mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
- HSV transform added
- Moved transform of led values to before the device write so transform changes are taken into account
This commit is contained in:
parent
271917bac7
commit
ee7a596d53
@ -12,11 +12,14 @@
|
|||||||
},
|
},
|
||||||
"color" :
|
"color" :
|
||||||
{
|
{
|
||||||
|
"hsv" : {
|
||||||
|
"saturationGain" : 1.0,
|
||||||
|
"valueGain" : 1.0
|
||||||
|
},
|
||||||
"red" :
|
"red" :
|
||||||
{
|
{
|
||||||
"threshold" : 0.0,
|
"threshold" : 0.0,
|
||||||
"gamma" : 1.0,
|
"gamma" : 1.0,
|
||||||
"adjust" : 1.0,
|
|
||||||
"blacklevel" : 0.0,
|
"blacklevel" : 0.0,
|
||||||
"whitelevel" : 1.0
|
"whitelevel" : 1.0
|
||||||
},
|
},
|
||||||
@ -24,7 +27,6 @@
|
|||||||
{
|
{
|
||||||
"threshold" : 0.0,
|
"threshold" : 0.0,
|
||||||
"gamma" : 1.0,
|
"gamma" : 1.0,
|
||||||
"adjust" : 1.0,
|
|
||||||
"blacklevel" : 0.0,
|
"blacklevel" : 0.0,
|
||||||
"whitelevel" : 1.0
|
"whitelevel" : 1.0
|
||||||
},
|
},
|
||||||
@ -32,7 +34,6 @@
|
|||||||
{
|
{
|
||||||
"threshold" : 0.0,
|
"threshold" : 0.0,
|
||||||
"gamma" : 1.0,
|
"gamma" : 1.0,
|
||||||
"adjust" : 1.0,
|
|
||||||
"blacklevel" : 0.0,
|
"blacklevel" : 0.0,
|
||||||
"whitelevel" : 1.0
|
"whitelevel" : 1.0
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,23 @@
|
|||||||
"type":"object",
|
"type":"object",
|
||||||
"required":true,
|
"required":true,
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"hsv" : {
|
||||||
|
"type" : "object",
|
||||||
|
"required" : true,
|
||||||
|
"properties" : {
|
||||||
|
"saturationGain" : {
|
||||||
|
"type" : "number",
|
||||||
|
"required" : true,
|
||||||
|
"minimum" : 0.0
|
||||||
|
},
|
||||||
|
"valueGain" : {
|
||||||
|
"type" : "number",
|
||||||
|
"required" : true,
|
||||||
|
"minimum" : 0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties" : false
|
||||||
|
},
|
||||||
"red": {
|
"red": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":true,
|
"required":true,
|
||||||
@ -41,10 +58,6 @@
|
|||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"adjust": {
|
|
||||||
"type":"number",
|
|
||||||
"required":true
|
|
||||||
},
|
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
@ -55,7 +68,9 @@
|
|||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true,
|
||||||
|
"minimum" : 0.0,
|
||||||
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -67,13 +82,19 @@
|
|||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"adjust": {
|
|
||||||
"type":"number",
|
|
||||||
"required":true
|
|
||||||
},
|
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
|
},
|
||||||
|
"whitelevel": {
|
||||||
|
"type":"number",
|
||||||
|
"required":true
|
||||||
|
},
|
||||||
|
"threshold": {
|
||||||
|
"type":"number",
|
||||||
|
"required":true,
|
||||||
|
"minimum" : 0.0,
|
||||||
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -85,13 +106,19 @@
|
|||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"adjust": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
|
},
|
||||||
|
"threshold": {
|
||||||
|
"type":"number",
|
||||||
|
"required":true,
|
||||||
|
"minimum" : 0.0,
|
||||||
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
#include <hyperion/PriorityMuxer.h>
|
#include <hyperion/PriorityMuxer.h>
|
||||||
|
|
||||||
// Forward class declaration
|
// Forward class declaration
|
||||||
namespace hyperion { class ColorTransform; }
|
namespace hyperion {
|
||||||
|
class HsvTransform;
|
||||||
|
class ColorTransform;
|
||||||
|
}
|
||||||
|
|
||||||
class Hyperion : public QObject
|
class Hyperion : public QObject
|
||||||
{
|
{
|
||||||
@ -27,12 +29,12 @@ public:
|
|||||||
|
|
||||||
enum Color
|
enum Color
|
||||||
{
|
{
|
||||||
RED, GREEN, BLUE
|
RED, GREEN, BLUE, INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Transform
|
enum Transform
|
||||||
{
|
{
|
||||||
THRESHOLD, GAMMA, BLACKLEVEL, WHITELEVEL
|
SATURATION_GAIN, VALUE_GAIN, THRESHOLD, GAMMA, BLACKLEVEL, WHITELEVEL
|
||||||
};
|
};
|
||||||
|
|
||||||
static LedString createLedString(const Json::Value& ledsConfig);
|
static LedString createLedString(const Json::Value& ledsConfig);
|
||||||
@ -69,9 +71,10 @@ private:
|
|||||||
|
|
||||||
PriorityMuxer _muxer;
|
PriorityMuxer _muxer;
|
||||||
|
|
||||||
hyperion::ColorTransform* _redTransform;
|
hyperion::HsvTransform * _hsvTransform;
|
||||||
hyperion::ColorTransform* _greenTransform;
|
hyperion::ColorTransform * _redTransform;
|
||||||
hyperion::ColorTransform* _blueTransform;
|
hyperion::ColorTransform * _greenTransform;
|
||||||
|
hyperion::ColorTransform * _blueTransform;
|
||||||
|
|
||||||
LedDevice* _device;
|
LedDevice* _device;
|
||||||
|
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
#include <hyperion/ImageProcessorFactory.h>
|
#include <hyperion/ImageProcessorFactory.h>
|
||||||
|
|
||||||
// Forward class declaration
|
// Forward class declaration
|
||||||
namespace hyperion { class ImageToLedsMap;
|
namespace hyperion { class ImageToLedsMap; }
|
||||||
class ColorTransform; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ImageProcessor translates an RGB-image to RGB-values for the leds. The processing is
|
* The ImageProcessor translates an RGB-image to RGB-values for the leds. The processing is
|
||||||
|
@ -19,6 +19,7 @@ SET(Hyperion_HEADERS
|
|||||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
|
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
|
||||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.h
|
${CURRENT_SOURCE_DIR}/ImageToLedsMap.h
|
||||||
${CURRENT_SOURCE_DIR}/ColorTransform.h
|
${CURRENT_SOURCE_DIR}/ColorTransform.h
|
||||||
|
${CURRENT_SOURCE_DIR}/HsvTransform.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(Hyperion_SOURCES
|
SET(Hyperion_SOURCES
|
||||||
@ -32,6 +33,7 @@ SET(Hyperion_SOURCES
|
|||||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
|
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
|
||||||
|
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
||||||
|
134
libsrc/hyperion/HsvTransform.cpp
Normal file
134
libsrc/hyperion/HsvTransform.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "HsvTransform.h"
|
||||||
|
|
||||||
|
using namespace hyperion;
|
||||||
|
|
||||||
|
HsvTransform::HsvTransform() :
|
||||||
|
_saturationGain(1.0),
|
||||||
|
_valueGain(1.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HsvTransform::HsvTransform(double saturationGain, double valueGain) :
|
||||||
|
_saturationGain(saturationGain),
|
||||||
|
_valueGain(valueGain)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HsvTransform::~HsvTransform()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void HsvTransform::setSaturationGain(double saturationGain)
|
||||||
|
{
|
||||||
|
_saturationGain = saturationGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
double HsvTransform::getSaturationGain() const
|
||||||
|
{
|
||||||
|
return _saturationGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HsvTransform::setValueGain(double valueGain)
|
||||||
|
{
|
||||||
|
_valueGain = valueGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
double HsvTransform::getValueGain() const
|
||||||
|
{
|
||||||
|
return _valueGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HsvTransform::transform(uint8_t & red, uint8_t & green, uint8_t & blue) const
|
||||||
|
{
|
||||||
|
if (_saturationGain != 1.0 || _valueGain != 1.0)
|
||||||
|
{
|
||||||
|
uint8_t hue, saturation, value;
|
||||||
|
rgb2hsv(red, green, blue, hue, saturation, value);
|
||||||
|
|
||||||
|
int s = saturation * _saturationGain;
|
||||||
|
if (s > 255)
|
||||||
|
saturation = 255;
|
||||||
|
else
|
||||||
|
saturation = s;
|
||||||
|
|
||||||
|
int v = value * _valueGain;
|
||||||
|
if (v > 255)
|
||||||
|
value = 255;
|
||||||
|
else
|
||||||
|
value = v;
|
||||||
|
|
||||||
|
hsv2rgb(hue, saturation, value, red, green, blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HsvTransform::rgb2hsv(uint8_t red, uint8_t green, uint8_t blue, uint8_t & hue, uint8_t & saturation, uint8_t & value)
|
||||||
|
{
|
||||||
|
uint8_t rgbMin, rgbMax;
|
||||||
|
|
||||||
|
rgbMin = red < green ? (red < blue ? red : blue) : (green < blue ? green : blue);
|
||||||
|
rgbMax = red > green ? (red > blue ? red : blue) : (green > blue ? green : blue);
|
||||||
|
|
||||||
|
value = rgbMax;
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
hue = 0;
|
||||||
|
saturation = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saturation = 255 * long(rgbMax - rgbMin) / value;
|
||||||
|
if (saturation == 0)
|
||||||
|
{
|
||||||
|
hue = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rgbMax == red)
|
||||||
|
hue = 0 + 43 * (green - blue) / (rgbMax - rgbMin);
|
||||||
|
else if (rgbMax == green)
|
||||||
|
hue = 85 + 43 * (blue - red) / (rgbMax - rgbMin);
|
||||||
|
else
|
||||||
|
hue = 171 + 43 * (red - green) / (rgbMax - rgbMin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HsvTransform::hsv2rgb(uint8_t hue, uint8_t saturation, uint8_t value, uint8_t & red, uint8_t & green, uint8_t & blue)
|
||||||
|
{
|
||||||
|
uint8_t region, remainder, p, q, t;
|
||||||
|
|
||||||
|
if (saturation == 0)
|
||||||
|
{
|
||||||
|
red = value;
|
||||||
|
green = value;
|
||||||
|
blue = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
region = hue / 43;
|
||||||
|
remainder = (hue - (region * 43)) * 6;
|
||||||
|
|
||||||
|
p = (value * (255 - saturation)) >> 8;
|
||||||
|
q = (value * (255 - ((saturation * remainder) >> 8))) >> 8;
|
||||||
|
t = (value * (255 - ((saturation * (255 - remainder)) >> 8))) >> 8;
|
||||||
|
|
||||||
|
switch (region)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
red = value; green = t; blue = p;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
red = q; green = value; blue = p;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
red = p; green = value; blue = t;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
red = p; green = q; blue = value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
red = t; green = p; blue = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
red = value; green = p; blue = q;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
33
libsrc/hyperion/HsvTransform.h
Normal file
33
libsrc/hyperion/HsvTransform.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace hyperion
|
||||||
|
{
|
||||||
|
|
||||||
|
class HsvTransform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HsvTransform();
|
||||||
|
HsvTransform(double saturationGain, double valueGain);
|
||||||
|
~HsvTransform();
|
||||||
|
|
||||||
|
void setSaturationGain(double saturationGain);
|
||||||
|
double getSaturationGain() const;
|
||||||
|
|
||||||
|
void setValueGain(double valueGain);
|
||||||
|
double getValueGain() const;
|
||||||
|
|
||||||
|
void transform(uint8_t & red, uint8_t & green, uint8_t & blue) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// integer version of the conversion are faster, but a little less accurate
|
||||||
|
static void rgb2hsv(uint8_t red, uint8_t green, uint8_t blue, uint8_t & hue, uint8_t & saturation, uint8_t & value);
|
||||||
|
static void hsv2rgb(uint8_t hue, uint8_t saturation, uint8_t value, uint8_t & red, uint8_t & green, uint8_t & blue);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double _saturationGain;
|
||||||
|
double _valueGain;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace hyperion
|
@ -15,6 +15,7 @@
|
|||||||
#include "LedDeviceWs2801.h"
|
#include "LedDeviceWs2801.h"
|
||||||
#include "LedDeviceTest.h"
|
#include "LedDeviceTest.h"
|
||||||
#include "ColorTransform.h"
|
#include "ColorTransform.h"
|
||||||
|
#include "HsvTransform.h"
|
||||||
|
|
||||||
using namespace hyperion;
|
using namespace hyperion;
|
||||||
|
|
||||||
@ -45,6 +46,11 @@ LedDevice* constructDevice(const Json::Value& deviceConfig)
|
|||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HsvTransform * createHsvTransform(const Json::Value & hsvConfig)
|
||||||
|
{
|
||||||
|
return new HsvTransform(hsvConfig["saturationGain"].asDouble(), hsvConfig["valueGain"].asDouble());
|
||||||
|
}
|
||||||
|
|
||||||
ColorTransform* createColorTransform(const Json::Value& colorConfig)
|
ColorTransform* createColorTransform(const Json::Value& colorConfig)
|
||||||
{
|
{
|
||||||
const double threshold = colorConfig["threshold"].asDouble();
|
const double threshold = colorConfig["threshold"].asDouble();
|
||||||
@ -78,6 +84,7 @@ LedString Hyperion::createLedString(const Json::Value& ledsConfig)
|
|||||||
Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
||||||
_ledString(createLedString(jsonConfig["leds"])),
|
_ledString(createLedString(jsonConfig["leds"])),
|
||||||
_muxer(_ledString.leds().size()),
|
_muxer(_ledString.leds().size()),
|
||||||
|
_hsvTransform(createHsvTransform(jsonConfig["color"]["hsv"])),
|
||||||
_redTransform(createColorTransform(jsonConfig["color"]["red"])),
|
_redTransform(createColorTransform(jsonConfig["color"]["red"])),
|
||||||
_greenTransform(createColorTransform(jsonConfig["color"]["green"])),
|
_greenTransform(createColorTransform(jsonConfig["color"]["green"])),
|
||||||
_blueTransform(createColorTransform(jsonConfig["color"]["blue"])),
|
_blueTransform(createColorTransform(jsonConfig["color"]["blue"])),
|
||||||
@ -99,6 +106,9 @@ Hyperion::~Hyperion()
|
|||||||
// Delete the Led-String
|
// Delete the Led-String
|
||||||
delete _device;
|
delete _device;
|
||||||
|
|
||||||
|
// delete he hsv transform
|
||||||
|
delete _hsvTransform;
|
||||||
|
|
||||||
// Delete the color-transform
|
// Delete the color-transform
|
||||||
delete _blueTransform;
|
delete _blueTransform;
|
||||||
delete _greenTransform;
|
delete _greenTransform;
|
||||||
@ -121,14 +131,6 @@ void Hyperion::setColor(int priority, RgbColor & color, const int timeout_ms)
|
|||||||
|
|
||||||
void Hyperion::setColors(int priority, std::vector<RgbColor>& ledColors, const int timeout_ms)
|
void Hyperion::setColors(int priority, std::vector<RgbColor>& ledColors, const int timeout_ms)
|
||||||
{
|
{
|
||||||
// Apply the transform to each led and color-channel
|
|
||||||
for (RgbColor& color : ledColors)
|
|
||||||
{
|
|
||||||
color.red = _redTransform->transform(color.red);
|
|
||||||
color.green = _greenTransform->transform(color.green);
|
|
||||||
color.blue = _blueTransform->transform(color.blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeout_ms > 0)
|
if (timeout_ms > 0)
|
||||||
{
|
{
|
||||||
const uint64_t timeoutTime = QDateTime::currentMSecsSinceEpoch() + timeout_ms;
|
const uint64_t timeoutTime = QDateTime::currentMSecsSinceEpoch() + timeout_ms;
|
||||||
@ -161,27 +163,40 @@ void Hyperion::setTransform(Hyperion::Transform transform, Hyperion::Color color
|
|||||||
t = _blueTransform;
|
t = _blueTransform;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set transform value
|
// set transform value
|
||||||
switch (transform)
|
switch (transform)
|
||||||
{
|
{
|
||||||
|
case SATURATION_GAIN:
|
||||||
|
_hsvTransform->setSaturationGain(value);
|
||||||
|
break;
|
||||||
|
case VALUE_GAIN:
|
||||||
|
_hsvTransform->setValueGain(value);
|
||||||
|
break;
|
||||||
case THRESHOLD:
|
case THRESHOLD:
|
||||||
|
assert (t != nullptr);
|
||||||
t->setThreshold(value);
|
t->setThreshold(value);
|
||||||
break;
|
break;
|
||||||
case GAMMA:
|
case GAMMA:
|
||||||
|
assert (t != nullptr);
|
||||||
t->setGamma(value);
|
t->setGamma(value);
|
||||||
break;
|
break;
|
||||||
case BLACKLEVEL:
|
case BLACKLEVEL:
|
||||||
|
assert (t != nullptr);
|
||||||
t->setBlacklevel(value);
|
t->setBlacklevel(value);
|
||||||
break;
|
break;
|
||||||
case WHITELEVEL:
|
case WHITELEVEL:
|
||||||
|
assert (t != nullptr);
|
||||||
t->setWhitelevel(value);
|
t->setWhitelevel(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update the led output
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::clear(int priority)
|
void Hyperion::clear(int priority)
|
||||||
@ -222,19 +237,27 @@ double Hyperion::getTransform(Hyperion::Transform transform, Hyperion::Color col
|
|||||||
t = _blueTransform;
|
t = _blueTransform;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set transform value
|
// set transform value
|
||||||
switch (transform)
|
switch (transform)
|
||||||
{
|
{
|
||||||
|
case SATURATION_GAIN:
|
||||||
|
return _hsvTransform->getSaturationGain();
|
||||||
|
case VALUE_GAIN:
|
||||||
|
return _hsvTransform->getValueGain();
|
||||||
case THRESHOLD:
|
case THRESHOLD:
|
||||||
|
assert (t != nullptr);
|
||||||
return t->getThreshold();
|
return t->getThreshold();
|
||||||
case GAMMA:
|
case GAMMA:
|
||||||
|
assert (t != nullptr);
|
||||||
return t->getGamma();
|
return t->getGamma();
|
||||||
case BLACKLEVEL:
|
case BLACKLEVEL:
|
||||||
|
assert (t != nullptr);
|
||||||
return t->getBlacklevel();
|
return t->getBlacklevel();
|
||||||
case WHITELEVEL:
|
case WHITELEVEL:
|
||||||
|
assert (t != nullptr);
|
||||||
return t->getWhitelevel();
|
return t->getWhitelevel();
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -262,8 +285,18 @@ void Hyperion::update()
|
|||||||
int priority = _muxer.getCurrentPriority();
|
int priority = _muxer.getCurrentPriority();
|
||||||
const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority);
|
const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority);
|
||||||
|
|
||||||
|
// Apply the transform to each led and color-channel
|
||||||
|
std::vector<RgbColor> ledColors(priorityInfo.ledColors);
|
||||||
|
for (RgbColor& color : ledColors)
|
||||||
|
{
|
||||||
|
_hsvTransform->transform(color.red, color.green, color.blue);
|
||||||
|
color.red = _redTransform->transform(color.red);
|
||||||
|
color.green = _greenTransform->transform(color.green);
|
||||||
|
color.blue = _blueTransform->transform(color.blue);
|
||||||
|
}
|
||||||
|
|
||||||
// Write the data to the device
|
// Write the data to the device
|
||||||
_device->write(priorityInfo.ledColors);
|
_device->write(ledColors);
|
||||||
|
|
||||||
// Start the timeout-timer
|
// Start the timeout-timer
|
||||||
if (priorityInfo.timeoutTime_ms == -1)
|
if (priorityInfo.timeoutTime_ms == -1)
|
||||||
|
@ -171,6 +171,8 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &message)
|
|||||||
|
|
||||||
// collect transform information
|
// collect transform information
|
||||||
Json::Value & transform = info["transform"];
|
Json::Value & transform = info["transform"];
|
||||||
|
transform["saturationGain"] = _hyperion->getTransform(Hyperion::SATURATION_GAIN, Hyperion::INVALID);
|
||||||
|
transform["valueGain"] = _hyperion->getTransform(Hyperion::VALUE_GAIN, Hyperion::INVALID);
|
||||||
Json::Value & threshold = transform["threshold"];
|
Json::Value & threshold = transform["threshold"];
|
||||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::RED));
|
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::RED));
|
||||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::GREEN));
|
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::GREEN));
|
||||||
@ -217,6 +219,16 @@ void JsonClientConnection::handleTransformCommand(const Json::Value &message)
|
|||||||
{
|
{
|
||||||
const Json::Value & transform = message["transform"];
|
const Json::Value & transform = message["transform"];
|
||||||
|
|
||||||
|
if (transform.isMember("saturationGain"))
|
||||||
|
{
|
||||||
|
_hyperion->setTransform(Hyperion::SATURATION_GAIN, Hyperion::INVALID, transform["saturationGain"].asDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transform.isMember("valueGain"))
|
||||||
|
{
|
||||||
|
_hyperion->setTransform(Hyperion::VALUE_GAIN, Hyperion::INVALID, transform["valueGain"].asDouble());
|
||||||
|
}
|
||||||
|
|
||||||
if (transform.isMember("threshold"))
|
if (transform.isMember("threshold"))
|
||||||
{
|
{
|
||||||
const Json::Value & threshold = transform["threshold"];
|
const Json::Value & threshold = transform["threshold"];
|
||||||
|
@ -11,6 +11,16 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"required": true,
|
"required": true,
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"saturationGain" : {
|
||||||
|
"type" : "double",
|
||||||
|
"required" : false,
|
||||||
|
"minimum" : 0.0
|
||||||
|
},
|
||||||
|
"valueGain" : {
|
||||||
|
"type" : "double",
|
||||||
|
"required" : false,
|
||||||
|
"minimum" : 0.0
|
||||||
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"required": false,
|
"required": false,
|
||||||
|
@ -30,5 +30,5 @@ qt4_use_modules(hyperion-remote
|
|||||||
Network)
|
Network)
|
||||||
|
|
||||||
target_link_libraries(hyperion-remote
|
target_link_libraries(hyperion-remote
|
||||||
hyperion-utils
|
jsoncpp
|
||||||
getoptPlusPlus)
|
getoptPlusPlus)
|
||||||
|
@ -160,7 +160,7 @@ void JsonConnection::clearAll()
|
|||||||
parseReply(reply);
|
parseReply(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonConnection::setTransform(ColorTransformValues *threshold, ColorTransformValues *gamma, ColorTransformValues *blacklevel, ColorTransformValues *whitelevel)
|
void JsonConnection::setTransform(double * saturation, double * value, ColorTransformValues *threshold, ColorTransformValues *gamma, ColorTransformValues *blacklevel, ColorTransformValues *whitelevel)
|
||||||
{
|
{
|
||||||
std::cout << "Set color transforms" << std::endl;
|
std::cout << "Set color transforms" << std::endl;
|
||||||
|
|
||||||
@ -169,6 +169,16 @@ void JsonConnection::setTransform(ColorTransformValues *threshold, ColorTransfor
|
|||||||
command["command"] = "transform";
|
command["command"] = "transform";
|
||||||
Json::Value & transform = command["transform"];
|
Json::Value & transform = command["transform"];
|
||||||
|
|
||||||
|
if (saturation != nullptr)
|
||||||
|
{
|
||||||
|
transform["saturationGain"] = *saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != nullptr)
|
||||||
|
{
|
||||||
|
transform["valueGain"] = *value;
|
||||||
|
}
|
||||||
|
|
||||||
if (threshold != nullptr)
|
if (threshold != nullptr)
|
||||||
{
|
{
|
||||||
Json::Value & v = transform["threshold"];
|
Json::Value & v = transform["threshold"];
|
||||||
|
@ -39,7 +39,13 @@ public:
|
|||||||
|
|
||||||
/// Set the color transform of the leds
|
/// Set the color transform of the leds
|
||||||
/// Note that providing a NULL will leave the settings on the server unchanged
|
/// Note that providing a NULL will leave the settings on the server unchanged
|
||||||
void setTransform(ColorTransformValues * threshold, ColorTransformValues * gamma, ColorTransformValues * blacklevel, ColorTransformValues * whitelevel);
|
void setTransform(
|
||||||
|
double * saturation,
|
||||||
|
double * value,
|
||||||
|
ColorTransformValues * threshold,
|
||||||
|
ColorTransformValues * gamma,
|
||||||
|
ColorTransformValues * blacklevel,
|
||||||
|
ColorTransformValues * whitelevel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Send a json command message and receive its reply
|
/// Send a json command message and receive its reply
|
||||||
|
@ -42,9 +42,11 @@ int main(int argc, char * argv[])
|
|||||||
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]");
|
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]");
|
||||||
ColorParameter & argColor = parameters.add<ColorParameter> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name)");
|
ColorParameter & argColor = parameters.add<ColorParameter> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name)");
|
||||||
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
|
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
|
||||||
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('s', "info" , "List server info");
|
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "List server info");
|
||||||
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
|
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
|
||||||
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clearall" , "Clear data for all active priority channels");
|
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clearall" , "Clear data for all active priority channels");
|
||||||
|
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "Set the HSV saturation gain of the leds");
|
||||||
|
DoubleParameter & argValue = parameters.add<DoubleParameter> ('v', "value ", "Set the HSV value gain of the leds");
|
||||||
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)");
|
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)");
|
||||||
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
|
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
|
||||||
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||||
@ -68,7 +70,7 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if at least one of the available color transforms is set
|
// check if at least one of the available color transforms is set
|
||||||
bool colorTransform = argThreshold.isSet() || argGamma.isSet() || argBlacklevel.isSet() || argWhitelevel.isSet();
|
bool colorTransform = argSaturation.isSet() || argValue.isSet() || argThreshold.isSet() || argGamma.isSet() || argBlacklevel.isSet() || argWhitelevel.isSet();
|
||||||
|
|
||||||
// check that exactly one command was given
|
// check that exactly one command was given
|
||||||
int commandCount = count({argColor.isSet(), argImage.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), colorTransform});
|
int commandCount = count({argColor.isSet(), argImage.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), colorTransform});
|
||||||
@ -81,6 +83,8 @@ int main(int argc, char * argv[])
|
|||||||
std::cerr << " " << argClear.usageLine() << std::endl;
|
std::cerr << " " << argClear.usageLine() << std::endl;
|
||||||
std::cerr << " " << argClearAll.usageLine() << std::endl;
|
std::cerr << " " << argClearAll.usageLine() << std::endl;
|
||||||
std::cerr << "or one or more of the available color transformations:" << std::endl;
|
std::cerr << "or one or more of the available color transformations:" << std::endl;
|
||||||
|
std::cerr << " " << argSaturation.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argValue.usageLine() << std::endl;
|
||||||
std::cerr << " " << argThreshold.usageLine() << std::endl;
|
std::cerr << " " << argThreshold.usageLine() << std::endl;
|
||||||
std::cerr << " " << argGamma.usageLine() << std::endl;
|
std::cerr << " " << argGamma.usageLine() << std::endl;
|
||||||
std::cerr << " " << argBlacklevel.usageLine() << std::endl;
|
std::cerr << " " << argBlacklevel.usageLine() << std::endl;
|
||||||
@ -115,14 +119,19 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
else if (colorTransform)
|
else if (colorTransform)
|
||||||
{
|
{
|
||||||
|
double saturation, value;
|
||||||
ColorTransformValues threshold, gamma, blacklevel, whitelevel;
|
ColorTransformValues threshold, gamma, blacklevel, whitelevel;
|
||||||
|
|
||||||
|
if (argSaturation.isSet()) saturation = argSaturation.getValue();
|
||||||
|
if (argValue.isSet()) value = argValue.getValue();
|
||||||
if (argThreshold.isSet()) threshold = argThreshold.getValue();
|
if (argThreshold.isSet()) threshold = argThreshold.getValue();
|
||||||
if (argGamma.isSet()) gamma = argGamma.getValue();
|
if (argGamma.isSet()) gamma = argGamma.getValue();
|
||||||
if (argBlacklevel.isSet()) blacklevel = argBlacklevel.getValue();
|
if (argBlacklevel.isSet()) blacklevel = argBlacklevel.getValue();
|
||||||
if (argWhitelevel.isSet()) whitelevel = argWhitelevel.getValue();
|
if (argWhitelevel.isSet()) whitelevel = argWhitelevel.getValue();
|
||||||
|
|
||||||
connection.setTransform(
|
connection.setTransform(
|
||||||
|
argSaturation.isSet() ? &saturation : nullptr,
|
||||||
|
argValue.isSet() ? &value : nullptr,
|
||||||
argThreshold.isSet() ? &threshold : nullptr,
|
argThreshold.isSet() ? &threshold : nullptr,
|
||||||
argGamma.isSet() ? &gamma : nullptr,
|
argGamma.isSet() ? &gamma : nullptr,
|
||||||
argBlacklevel.isSet() ? &blacklevel : nullptr,
|
argBlacklevel.isSet() ? &blacklevel : nullptr,
|
||||||
|
Loading…
Reference in New Issue
Block a user