mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Implemented the multi-color transform including in hyperion-remote
Former-commit-id: ebdb0688b47d51bd6dccf6dafd580d3ce9ed80a7
This commit is contained in:
parent
958feabf5b
commit
826b964bf6
@ -34,6 +34,10 @@
|
|||||||
/// - 'updateFrequency' The update frequency of the leds in Hz
|
/// - 'updateFrequency' The update frequency of the leds in Hz
|
||||||
"color" :
|
"color" :
|
||||||
{
|
{
|
||||||
|
"transforms" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id" : "default",
|
||||||
"hsv" :
|
"hsv" :
|
||||||
{
|
{
|
||||||
"saturationGain" : 1.0000,
|
"saturationGain" : 1.0000,
|
||||||
@ -60,6 +64,8 @@
|
|||||||
"blacklevel" : 0.0000,
|
"blacklevel" : 0.0000,
|
||||||
"whitelevel" : 1.0000
|
"whitelevel" : 1.0000
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
"smoothing" :
|
"smoothing" :
|
||||||
{
|
{
|
||||||
"type" : "none",
|
"type" : "none",
|
||||||
|
26
include/hyperion/ColorTransform.h
Normal file
26
include/hyperion/ColorTransform.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Utils includes
|
||||||
|
#include <utils/RgbChannelTransform.h>
|
||||||
|
#include <utils/HsvTransform.h>
|
||||||
|
|
||||||
|
class ColorTransform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// Unique identifier for this color transform
|
||||||
|
std::string _id;
|
||||||
|
|
||||||
|
/// The RED-Channel (RGB) transform
|
||||||
|
RgbChannelTransform _rgbRedTransform;
|
||||||
|
/// The GREEN-Channel (RGB) transform
|
||||||
|
RgbChannelTransform _rgbGreenTransform;
|
||||||
|
/// The BLUE-Channel (RGB) transform
|
||||||
|
RgbChannelTransform _rgbBlueTransform;
|
||||||
|
|
||||||
|
/// The HSV Transform for applying Saturation and Value transforms
|
||||||
|
HsvTransform _hsvTransform;
|
||||||
|
};
|
@ -16,6 +16,7 @@
|
|||||||
#include <hyperion/PriorityMuxer.h>
|
#include <hyperion/PriorityMuxer.h>
|
||||||
|
|
||||||
// Forward class declaration
|
// Forward class declaration
|
||||||
|
class ColorTransform;
|
||||||
class HsvTransform;
|
class HsvTransform;
|
||||||
class RgbChannelTransform;
|
class RgbChannelTransform;
|
||||||
class MultiColorTransform;
|
class MultiColorTransform;
|
||||||
@ -89,15 +90,16 @@ public:
|
|||||||
void setColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms);
|
void setColors(int priority, const std::vector<ColorRgb> &ledColors, const int timeout_ms);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets/Updates a part of the color transformation.
|
/// Returns the list with unique transform identifiers
|
||||||
|
/// @return The list with transform identifiers
|
||||||
///
|
///
|
||||||
/// @param[in] transform The type of transform to configure
|
const std::vector<std::string> & getTransformIds() const;
|
||||||
/// @param[in] color The color channel to which the transform applies (only applicable for
|
|
||||||
/// Transform::THRESHOLD, Transform::GAMMA, Transform::BLACKLEVEL,
|
|
||||||
/// Transform::WHITELEVEL)
|
|
||||||
/// @param[in] value The new value for the given transform
|
|
||||||
///
|
///
|
||||||
void setTransform(Transform transform, RgbChannel color, double value);
|
/// Returns the ColorTransform with the given identifier
|
||||||
|
/// @return The transform with the given identifier (or nullptr if the identifier does not exist)
|
||||||
|
///
|
||||||
|
ColorTransform * getTransform(const std::string& id);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Clears the given priority channel. This will switch the led-colors to the colors of the next
|
/// Clears the given priority channel. This will switch the led-colors to the colors of the next
|
||||||
@ -112,18 +114,6 @@ public:
|
|||||||
///
|
///
|
||||||
void clearall();
|
void clearall();
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the value of a specific color transform
|
|
||||||
///
|
|
||||||
/// @param[in] transform The type of transform
|
|
||||||
/// @param[in] color The color channel to which the transform applies (only applicable for
|
|
||||||
/// Transform::THRESHOLD, Transform::GAMMA, Transform::BLACKLEVEL,
|
|
||||||
/// Transform::WHITELEVEL)
|
|
||||||
///
|
|
||||||
/// @return The value of the specified color transform
|
|
||||||
///
|
|
||||||
double getTransform(Transform transform, RgbChannel color) const;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a list of active priorities
|
/// Returns a list of active priorities
|
||||||
///
|
///
|
||||||
@ -147,8 +137,9 @@ public:
|
|||||||
static LedString createLedString(const Json::Value & ledsConfig);
|
static LedString createLedString(const Json::Value & ledsConfig);
|
||||||
|
|
||||||
static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
|
static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
|
||||||
|
static ColorTransform * createColorTransform(const Json::Value & transformConfig);
|
||||||
static HsvTransform * createHsvTransform(const Json::Value & hsvConfig);
|
static HsvTransform * createHsvTransform(const Json::Value & hsvConfig);
|
||||||
static RgbChannelTransform * createColorTransform(const Json::Value& colorConfig);
|
static RgbChannelTransform * createRgbChannelTransform(const Json::Value& colorConfig);
|
||||||
|
|
||||||
static LedDevice * createColorSmoothing(const Json::Value & smoothingConfig, LedDevice * ledDevice);
|
static LedDevice * createColorSmoothing(const Json::Value & smoothingConfig, LedDevice * ledDevice);
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ add_library(hyperion
|
|||||||
${Hyperion_SOURCES}
|
${Hyperion_SOURCES}
|
||||||
${Hyperion_RESOURCES_RCC}
|
${Hyperion_RESOURCES_RCC}
|
||||||
)
|
)
|
||||||
|
message("{QT_LIBRARIES} = ${QT_LIBRARIES}")
|
||||||
|
|
||||||
target_link_libraries(hyperion
|
target_link_libraries(hyperion
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
// QT includes
|
// QT includes
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
// JsonSchema include
|
// JsonSchema include
|
||||||
#include <utils/jsonschema/JsonFactory.h>
|
#include <utils/jsonschema/JsonFactory.h>
|
||||||
@ -153,29 +156,94 @@ Hyperion::ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
|
|||||||
return ORDER_RGB;
|
return ORDER_RGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorConfig)
|
ColorTransform * Hyperion::createColorTransform(const Json::Value & transformConfig)
|
||||||
{
|
{
|
||||||
MultiColorTransform * transform = new MultiColorTransform();
|
const std::string id = transformConfig.get("id", "default").asString();
|
||||||
if (!colorConfig.isArray())
|
|
||||||
{
|
|
||||||
// Old style color transformation config (just one for all leds)
|
|
||||||
const std::string id = "default";
|
|
||||||
|
|
||||||
RgbChannelTransform * redTransform = createColorTransform(colorConfig["red"]);
|
RgbChannelTransform * redTransform = createRgbChannelTransform(transformConfig["red"]);
|
||||||
RgbChannelTransform * greenTransform = createColorTransform(colorConfig["green"]);
|
RgbChannelTransform * greenTransform = createRgbChannelTransform(transformConfig["green"]);
|
||||||
RgbChannelTransform * blueTransform = createColorTransform(colorConfig["blue"]);
|
RgbChannelTransform * blueTransform = createRgbChannelTransform(transformConfig["blue"]);
|
||||||
|
|
||||||
HsvTransform * hsvTransform = createHsvTransform(colorConfig["hsv"]);
|
HsvTransform * hsvTransform = createHsvTransform(transformConfig["hsv"]);
|
||||||
transform->addTransform(id, *redTransform, *greenTransform, *blueTransform, *hsvTransform);
|
|
||||||
transform->setTransformForLed(id, 0, ledCnt-1);
|
|
||||||
|
|
||||||
|
ColorTransform * transform = new ColorTransform();
|
||||||
|
transform->_id = id;
|
||||||
|
transform->_rgbRedTransform = *redTransform;
|
||||||
|
transform->_rgbGreenTransform = *greenTransform;
|
||||||
|
transform->_rgbBlueTransform = *blueTransform;
|
||||||
|
transform->_hsvTransform = *hsvTransform;
|
||||||
|
|
||||||
|
// Cleanup the allocated individual transforms
|
||||||
delete redTransform;
|
delete redTransform;
|
||||||
delete greenTransform;
|
delete greenTransform;
|
||||||
delete blueTransform;
|
delete blueTransform;
|
||||||
|
delete hsvTransform;
|
||||||
|
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorConfig)
|
||||||
|
{
|
||||||
|
// Create the result, the transforms are added to this
|
||||||
|
MultiColorTransform * transform = new MultiColorTransform(ledCnt);
|
||||||
|
|
||||||
|
const Json::Value transformConfig = colorConfig.get("transform", Json::nullValue);
|
||||||
|
if (transformConfig.isNull())
|
||||||
|
{
|
||||||
|
// Old style color transformation config (just one for all leds)
|
||||||
|
ColorTransform * colorTransform = createColorTransform(colorConfig);
|
||||||
|
transform->addTransform(colorTransform);
|
||||||
|
transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1);
|
||||||
|
}
|
||||||
|
else if (!transformConfig.isArray())
|
||||||
|
{
|
||||||
|
ColorTransform * colorTransform = createColorTransform(transformConfig);
|
||||||
|
transform->addTransform(colorTransform);
|
||||||
|
transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
|
||||||
|
|
||||||
|
for (Json::UInt i = 0; i < transformConfig.size(); ++i)
|
||||||
|
{
|
||||||
|
const Json::Value & config = transformConfig[i];
|
||||||
|
ColorTransform * colorTransform = createColorTransform(config);
|
||||||
|
transform->addTransform(colorTransform);
|
||||||
|
|
||||||
|
const QString ledIndicesStr = config.get("leds", "").asCString();
|
||||||
|
if (!overallExp.exactMatch(ledIndicesStr))
|
||||||
|
{
|
||||||
|
std::cerr << "Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "ColorTransform '" << colorTransform->_id << "' => [";
|
||||||
|
|
||||||
|
const QStringList ledIndexList = ledIndicesStr.split(",");
|
||||||
|
for (int i=0; i<ledIndexList.size(); ++i) {
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
std::cout << ", ";
|
||||||
|
}
|
||||||
|
if (ledIndexList[i].contains("-"))
|
||||||
|
{
|
||||||
|
QStringList ledIndices = ledIndexList[i].split("-");
|
||||||
|
int startInd = ledIndices[0].toInt();
|
||||||
|
int endInd = ledIndices[1].toInt();
|
||||||
|
|
||||||
|
transform->setTransformForLed(colorTransform->_id, startInd, endInd);
|
||||||
|
std::cout << startInd << "-" << endInd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = ledIndexList[i].toInt();
|
||||||
|
transform->setTransformForLed(colorTransform->_id, index, index);
|
||||||
|
std::cout << index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "]" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
@ -188,7 +256,7 @@ HsvTransform * Hyperion::createHsvTransform(const Json::Value & hsvConfig)
|
|||||||
return new HsvTransform(saturationGain, valueGain);
|
return new HsvTransform(saturationGain, valueGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbChannelTransform* Hyperion::createColorTransform(const Json::Value& colorConfig)
|
RgbChannelTransform* Hyperion::createRgbChannelTransform(const Json::Value& colorConfig)
|
||||||
{
|
{
|
||||||
const double threshold = colorConfig.get("threshold", 0.0).asDouble();
|
const double threshold = colorConfig.get("threshold", 0.0).asDouble();
|
||||||
const double gamma = colorConfig.get("gamma", 1.0).asDouble();
|
const double gamma = colorConfig.get("gamma", 1.0).asDouble();
|
||||||
@ -276,6 +344,10 @@ Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
|||||||
_device(createDevice(jsonConfig["device"])),
|
_device(createDevice(jsonConfig["device"])),
|
||||||
_timer()
|
_timer()
|
||||||
{
|
{
|
||||||
|
if (!_raw2ledTransform->verifyTransforms())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Color transformation incorrectly set");
|
||||||
|
}
|
||||||
// initialize the image processor factory
|
// initialize the image processor factory
|
||||||
ImageProcessorFactory::getInstance().init(_ledString, jsonConfig["blackborderdetector"].get("enable", true).asBool());
|
ImageProcessorFactory::getInstance().init(_ledString, jsonConfig["blackborderdetector"].get("enable", true).asBool());
|
||||||
|
|
||||||
@ -336,59 +408,14 @@ void Hyperion::setColors(int priority, const std::vector<ColorRgb>& ledColors, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::setTransform(Hyperion::Transform transform, Hyperion::RgbChannel color, double value)
|
const std::vector<std::string> & Hyperion::getTransformIds() const
|
||||||
{
|
{
|
||||||
ColorTransform* colorTransform = _raw2ledTransform->getTransform("default");
|
return _raw2ledTransform->getTransformIds();
|
||||||
assert(colorTransform != nullptr);
|
}
|
||||||
|
|
||||||
// select the transform of the requested color
|
ColorTransform * Hyperion::getTransform(const std::string& id)
|
||||||
RgbChannelTransform * t = nullptr;
|
{
|
||||||
switch (color)
|
return _raw2ledTransform->getTransform(id);
|
||||||
{
|
|
||||||
case RED:
|
|
||||||
t = &(colorTransform->_rgbRedTransform);
|
|
||||||
break;
|
|
||||||
case GREEN:
|
|
||||||
t = &(colorTransform->_rgbGreenTransform);
|
|
||||||
break;
|
|
||||||
case BLUE:
|
|
||||||
t = &(colorTransform->_rgbBlueTransform);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set transform value
|
|
||||||
switch (transform)
|
|
||||||
{
|
|
||||||
case SATURATION_GAIN:
|
|
||||||
colorTransform->_hsvTransform.setSaturationGain(value);
|
|
||||||
break;
|
|
||||||
case VALUE_GAIN:
|
|
||||||
colorTransform->_hsvTransform.setValueGain(value);
|
|
||||||
break;
|
|
||||||
case THRESHOLD:
|
|
||||||
assert (t != nullptr);
|
|
||||||
t->setThreshold(value);
|
|
||||||
break;
|
|
||||||
case GAMMA:
|
|
||||||
assert (t != nullptr);
|
|
||||||
t->setGamma(value);
|
|
||||||
break;
|
|
||||||
case BLACKLEVEL:
|
|
||||||
assert (t != nullptr);
|
|
||||||
t->setBlacklevel(value);
|
|
||||||
break;
|
|
||||||
case WHITELEVEL:
|
|
||||||
assert (t != nullptr);
|
|
||||||
t->setWhitelevel(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the led output
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::clear(int priority)
|
void Hyperion::clear(int priority)
|
||||||
@ -413,54 +440,6 @@ void Hyperion::clearall()
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
double Hyperion::getTransform(Hyperion::Transform transform, Hyperion::RgbChannel color) const
|
|
||||||
{
|
|
||||||
ColorTransform * colorTransform = _raw2ledTransform->getTransform("default");
|
|
||||||
assert(colorTransform != nullptr);
|
|
||||||
|
|
||||||
// select the transform of the requested color
|
|
||||||
RgbChannelTransform * t = nullptr;
|
|
||||||
switch (color)
|
|
||||||
{
|
|
||||||
case RED:
|
|
||||||
t = &(colorTransform->_rgbRedTransform);
|
|
||||||
break;
|
|
||||||
case GREEN:
|
|
||||||
t = &(colorTransform->_rgbGreenTransform);
|
|
||||||
break;
|
|
||||||
case BLUE:
|
|
||||||
t = &(colorTransform->_rgbBlueTransform);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set transform value
|
|
||||||
switch (transform)
|
|
||||||
{
|
|
||||||
case SATURATION_GAIN:
|
|
||||||
return colorTransform->_hsvTransform.getSaturationGain();
|
|
||||||
case VALUE_GAIN:
|
|
||||||
return colorTransform->_hsvTransform.getValueGain();
|
|
||||||
case THRESHOLD:
|
|
||||||
assert (t != nullptr);
|
|
||||||
return t->getThreshold();
|
|
||||||
case GAMMA:
|
|
||||||
assert (t != nullptr);
|
|
||||||
return t->getGamma();
|
|
||||||
case BLACKLEVEL:
|
|
||||||
assert (t != nullptr);
|
|
||||||
return t->getBlacklevel();
|
|
||||||
case WHITELEVEL:
|
|
||||||
assert (t != nullptr);
|
|
||||||
return t->getWhitelevel();
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 999.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<int> Hyperion::getActivePriorities() const
|
QList<int> Hyperion::getActivePriorities() const
|
||||||
{
|
{
|
||||||
return _muxer.getPriorities();
|
return _muxer.getPriorities();
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
// Hyperion includes
|
// Hyperion includes
|
||||||
#include "MultiColorTransform.h"
|
#include "MultiColorTransform.h"
|
||||||
|
|
||||||
MultiColorTransform::MultiColorTransform()
|
MultiColorTransform::MultiColorTransform(const unsigned ledCnt) :
|
||||||
|
_ledTransforms(ledCnt, nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,33 +19,16 @@ MultiColorTransform::~MultiColorTransform()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiColorTransform::addTransform(const std::string & id,
|
void MultiColorTransform::addTransform(ColorTransform * transform)
|
||||||
const RgbChannelTransform & redTransform,
|
|
||||||
const RgbChannelTransform & greenTransform,
|
|
||||||
const RgbChannelTransform & blueTransform,
|
|
||||||
const HsvTransform & hsvTransform)
|
|
||||||
{
|
{
|
||||||
ColorTransform * transform = new ColorTransform();
|
_transformIds.push_back(transform->_id);
|
||||||
transform->_id = id;
|
|
||||||
|
|
||||||
transform->_rgbRedTransform = redTransform;
|
|
||||||
transform->_rgbGreenTransform = greenTransform;
|
|
||||||
transform->_rgbBlueTransform = blueTransform;
|
|
||||||
|
|
||||||
transform->_hsvTransform = hsvTransform;
|
|
||||||
|
|
||||||
_transform.push_back(transform);
|
_transform.push_back(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiColorTransform::setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
|
void MultiColorTransform::setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed)
|
||||||
{
|
{
|
||||||
assert(startLed <= endLed);
|
assert(startLed <= endLed);
|
||||||
|
assert(endLed < _ledTransforms.size());
|
||||||
// Make sure that there are at least enough led transforms to match the given indices
|
|
||||||
if (_ledTransforms.size() < endLed+1)
|
|
||||||
{
|
|
||||||
_ledTransforms.resize(endLed+1, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the identified transform (don't care if is nullptr)
|
// Get the identified transform (don't care if is nullptr)
|
||||||
ColorTransform * transform = getTransform(id);
|
ColorTransform * transform = getTransform(id);
|
||||||
@ -54,15 +38,23 @@ void MultiColorTransform::setTransformForLed(const std::string& id, const unsign
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> MultiColorTransform::getTransformIds()
|
bool MultiColorTransform::verifyTransforms() const
|
||||||
{
|
{
|
||||||
// Create the list on the fly
|
bool allLedsSet = true;
|
||||||
std::vector<std::string> transformIds;
|
for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed)
|
||||||
for (ColorTransform* transform : _transform)
|
|
||||||
{
|
{
|
||||||
transformIds.push_back(transform->_id);
|
if (_ledTransforms[iLed] == nullptr)
|
||||||
|
{
|
||||||
|
std::cerr << "No transform set for " << iLed << std::endl;
|
||||||
|
allLedsSet = false;
|
||||||
}
|
}
|
||||||
return transformIds;
|
}
|
||||||
|
return allLedsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> & MultiColorTransform::getTransformIds()
|
||||||
|
{
|
||||||
|
return _transformIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorTransform* MultiColorTransform::getTransform(const std::string& id)
|
ColorTransform* MultiColorTransform::getTransform(const std::string& id)
|
||||||
@ -85,7 +77,7 @@ std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<Colo
|
|||||||
// Create a copy, as we will do the rest of the transformation in place
|
// Create a copy, as we will do the rest of the transformation in place
|
||||||
std::vector<ColorRgb> ledColors(rawColors);
|
std::vector<ColorRgb> ledColors(rawColors);
|
||||||
|
|
||||||
const size_t itCnt = std::min(_transform.size(), rawColors.size());
|
const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size());
|
||||||
for (size_t i=0; i<itCnt; ++i)
|
for (size_t i=0; i<itCnt; ++i)
|
||||||
{
|
{
|
||||||
ColorTransform* transform = _ledTransforms[i];
|
ColorTransform* transform = _ledTransforms[i];
|
||||||
|
@ -6,21 +6,8 @@
|
|||||||
// Utils includes
|
// Utils includes
|
||||||
#include <utils/ColorRgb.h>
|
#include <utils/ColorRgb.h>
|
||||||
|
|
||||||
#include <utils/RgbChannelTransform.h>
|
// Hyperion includes
|
||||||
#include <utils/HsvTransform.h>
|
#include <hyperion/ColorTransform.h>
|
||||||
|
|
||||||
struct ColorTransform
|
|
||||||
{
|
|
||||||
std::string _id;
|
|
||||||
/// The RED-Channel (RGB) transform
|
|
||||||
RgbChannelTransform _rgbRedTransform;
|
|
||||||
/// The GREEN-Channel (RGB) transform
|
|
||||||
RgbChannelTransform _rgbGreenTransform;
|
|
||||||
/// The BLUE-Channel (RGB) transform
|
|
||||||
RgbChannelTransform _rgbBlueTransform;
|
|
||||||
/// The HSV Transform for applying Saturation and Value transforms
|
|
||||||
HsvTransform _hsvTransform;
|
|
||||||
};
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The LedColorTransform is responsible for performing color transformation from 'raw' colors
|
/// The LedColorTransform is responsible for performing color transformation from 'raw' colors
|
||||||
@ -29,22 +16,25 @@ struct ColorTransform
|
|||||||
class MultiColorTransform
|
class MultiColorTransform
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MultiColorTransform();
|
MultiColorTransform(const unsigned ledCnt);
|
||||||
~MultiColorTransform();
|
~MultiColorTransform();
|
||||||
|
|
||||||
void addTransform(const std::string & id,
|
/**
|
||||||
const RgbChannelTransform & redTransform,
|
* Adds a new ColorTransform to this MultiColorTransform
|
||||||
const RgbChannelTransform & greenTransform,
|
*
|
||||||
const RgbChannelTransform & blueTransform,
|
* @param transform The new ColorTransform (ownership is transfered)
|
||||||
const HsvTransform & hsvTransform);
|
*/
|
||||||
|
void addTransform(ColorTransform * transform);
|
||||||
|
|
||||||
void setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed);
|
void setTransformForLed(const std::string& id, const unsigned startLed, const unsigned endLed);
|
||||||
|
|
||||||
|
bool verifyTransforms() const;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the identifier of all the unique ColorTransform
|
/// Returns the identifier of all the unique ColorTransform
|
||||||
///
|
///
|
||||||
/// @return The list with unique id's of the ColorTransforms
|
/// @return The list with unique id's of the ColorTransforms
|
||||||
std::vector<std::string> getTransformIds();
|
const std::vector<std::string> & getTransformIds();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the pointer to the ColorTransform with the given id
|
/// Returns the pointer to the ColorTransform with the given id
|
||||||
@ -65,6 +55,9 @@ public:
|
|||||||
std::vector<ColorRgb> applyTransform(const std::vector<ColorRgb>& rawColors);
|
std::vector<ColorRgb> applyTransform(const std::vector<ColorRgb>& rawColors);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// List with transform ids
|
||||||
|
std::vector<std::string> _transformIds;
|
||||||
|
|
||||||
/// List with unique ColorTransforms
|
/// List with unique ColorTransforms
|
||||||
std::vector<ColorTransform*> _transform;
|
std::vector<ColorTransform*> _transform;
|
||||||
|
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
// hyperion util includes
|
// hyperion util includes
|
||||||
#include "hyperion/ImageProcessorFactory.h"
|
#include <hyperion/ImageProcessorFactory.h>
|
||||||
#include "hyperion/ImageProcessor.h"
|
#include <hyperion/ImageProcessor.h>
|
||||||
#include "utils/ColorRgb.h"
|
#include <hyperion/ColorTransform.h>
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
|
|
||||||
// project includes
|
// project includes
|
||||||
#include "JsonClientConnection.h"
|
#include "JsonClientConnection.h"
|
||||||
@ -173,25 +174,39 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collect transform information
|
// collect transform information
|
||||||
Json::Value & transform = info["transform"];
|
Json::Value & transformArray = info["transform"];
|
||||||
transform["saturationGain"] = _hyperion->getTransform(Hyperion::SATURATION_GAIN, Hyperion::INVALID);
|
for (const std::string& transformId : _hyperion->getTransformIds())
|
||||||
transform["valueGain"] = _hyperion->getTransform(Hyperion::VALUE_GAIN, Hyperion::INVALID);
|
{
|
||||||
|
const ColorTransform * colorTransform = _hyperion->getTransform(transformId);
|
||||||
|
if (colorTransform == nullptr)
|
||||||
|
{
|
||||||
|
std::cerr << "Incorrect color transform id: " << transformId << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value & transform = transformArray.append(Json::Value());
|
||||||
|
transform["id"] = transformId;
|
||||||
|
|
||||||
|
transform["saturationGain"] = colorTransform->_hsvTransform.getSaturationGain();
|
||||||
|
transform["valueGain"] = colorTransform->_hsvTransform.getValueGain();
|
||||||
|
|
||||||
Json::Value & threshold = transform["threshold"];
|
Json::Value & threshold = transform["threshold"];
|
||||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::RED));
|
threshold.append(colorTransform->_rgbRedTransform.getThreshold());
|
||||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::GREEN));
|
threshold.append(colorTransform->_rgbGreenTransform.getThreshold());
|
||||||
threshold.append(_hyperion->getTransform(Hyperion::THRESHOLD, Hyperion::BLUE));
|
threshold.append(colorTransform->_rgbBlueTransform.getThreshold());
|
||||||
Json::Value & gamma = transform["gamma"];
|
Json::Value & gamma = transform["gamma"];
|
||||||
gamma.append(_hyperion->getTransform(Hyperion::GAMMA, Hyperion::RED));
|
gamma.append(colorTransform->_rgbRedTransform.getGamma());
|
||||||
gamma.append(_hyperion->getTransform(Hyperion::GAMMA, Hyperion::GREEN));
|
gamma.append(colorTransform->_rgbGreenTransform.getGamma());
|
||||||
gamma.append(_hyperion->getTransform(Hyperion::GAMMA, Hyperion::BLUE));
|
gamma.append(colorTransform->_rgbBlueTransform.getGamma());
|
||||||
Json::Value & blacklevel = transform["blacklevel"];
|
Json::Value & blacklevel = transform["blacklevel"];
|
||||||
blacklevel.append(_hyperion->getTransform(Hyperion::BLACKLEVEL, Hyperion::RED));
|
blacklevel.append(colorTransform->_rgbRedTransform.getBlacklevel());
|
||||||
blacklevel.append(_hyperion->getTransform(Hyperion::BLACKLEVEL, Hyperion::GREEN));
|
blacklevel.append(colorTransform->_rgbGreenTransform.getBlacklevel());
|
||||||
blacklevel.append(_hyperion->getTransform(Hyperion::BLACKLEVEL, Hyperion::BLUE));
|
blacklevel.append(colorTransform->_rgbBlueTransform.getBlacklevel());
|
||||||
Json::Value & whitelevel = transform["whitelevel"];
|
Json::Value & whitelevel = transform["whitelevel"];
|
||||||
whitelevel.append(_hyperion->getTransform(Hyperion::WHITELEVEL, Hyperion::RED));
|
whitelevel.append(colorTransform->_rgbRedTransform.getWhitelevel());
|
||||||
whitelevel.append(_hyperion->getTransform(Hyperion::WHITELEVEL, Hyperion::GREEN));
|
whitelevel.append(colorTransform->_rgbGreenTransform.getWhitelevel());
|
||||||
whitelevel.append(_hyperion->getTransform(Hyperion::WHITELEVEL, Hyperion::BLUE));
|
whitelevel.append(colorTransform->_rgbBlueTransform.getWhitelevel());
|
||||||
|
}
|
||||||
|
|
||||||
// send the result
|
// send the result
|
||||||
sendMessage(result);
|
sendMessage(result);
|
||||||
@ -222,46 +237,54 @@ void JsonClientConnection::handleTransformCommand(const Json::Value &message)
|
|||||||
{
|
{
|
||||||
const Json::Value & transform = message["transform"];
|
const Json::Value & transform = message["transform"];
|
||||||
|
|
||||||
|
const std::string transformId = transform.get("id", _hyperion->getTransformIds().front()).asString();
|
||||||
|
ColorTransform * colorTransform = _hyperion->getTransform(transformId);
|
||||||
|
if (colorTransform == nullptr)
|
||||||
|
{
|
||||||
|
//sendErrorReply(std::string("Incorrect transform identifier: ") + transformId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (transform.isMember("saturationGain"))
|
if (transform.isMember("saturationGain"))
|
||||||
{
|
{
|
||||||
_hyperion->setTransform(Hyperion::SATURATION_GAIN, Hyperion::INVALID, transform["saturationGain"].asDouble());
|
colorTransform->_hsvTransform.setSaturationGain(transform["saturationGain"].asDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform.isMember("valueGain"))
|
if (transform.isMember("valueGain"))
|
||||||
{
|
{
|
||||||
_hyperion->setTransform(Hyperion::VALUE_GAIN, Hyperion::INVALID, transform["valueGain"].asDouble());
|
colorTransform->_hsvTransform.setValueGain(transform["valueGain"].asDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform.isMember("threshold"))
|
if (transform.isMember("threshold"))
|
||||||
{
|
{
|
||||||
const Json::Value & threshold = transform["threshold"];
|
const Json::Value & values = transform["threshold"];
|
||||||
_hyperion->setTransform(Hyperion::THRESHOLD, Hyperion::RED, threshold[0u].asDouble());
|
colorTransform->_rgbRedTransform .setThreshold(values[0u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::THRESHOLD, Hyperion::GREEN, threshold[1u].asDouble());
|
colorTransform->_rgbGreenTransform.setThreshold(values[1u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::THRESHOLD, Hyperion::BLUE, threshold[2u].asDouble());
|
colorTransform->_rgbBlueTransform .setThreshold(values[2u].asDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform.isMember("gamma"))
|
if (transform.isMember("gamma"))
|
||||||
{
|
{
|
||||||
const Json::Value & threshold = transform["gamma"];
|
const Json::Value & values = transform["gamma"];
|
||||||
_hyperion->setTransform(Hyperion::GAMMA, Hyperion::RED, threshold[0u].asDouble());
|
colorTransform->_rgbRedTransform .setGamma(values[0u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::GAMMA, Hyperion::GREEN, threshold[1u].asDouble());
|
colorTransform->_rgbGreenTransform.setGamma(values[1u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::GAMMA, Hyperion::BLUE, threshold[2u].asDouble());
|
colorTransform->_rgbBlueTransform .setGamma(values[2u].asDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform.isMember("blacklevel"))
|
if (transform.isMember("blacklevel"))
|
||||||
{
|
{
|
||||||
const Json::Value & threshold = transform["blacklevel"];
|
const Json::Value & values = transform["blacklevel"];
|
||||||
_hyperion->setTransform(Hyperion::BLACKLEVEL, Hyperion::RED, threshold[0u].asDouble());
|
colorTransform->_rgbRedTransform .setBlacklevel(values[0u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::BLACKLEVEL, Hyperion::GREEN, threshold[1u].asDouble());
|
colorTransform->_rgbGreenTransform.setBlacklevel(values[1u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::BLACKLEVEL, Hyperion::BLUE, threshold[2u].asDouble());
|
colorTransform->_rgbBlueTransform .setBlacklevel(values[2u].asDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform.isMember("whitelevel"))
|
if (transform.isMember("whitelevel"))
|
||||||
{
|
{
|
||||||
const Json::Value & threshold = transform["whitelevel"];
|
const Json::Value & values = transform["whitelevel"];
|
||||||
_hyperion->setTransform(Hyperion::WHITELEVEL, Hyperion::RED, threshold[0u].asDouble());
|
colorTransform->_rgbRedTransform .setWhitelevel(values[0u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::WHITELEVEL, Hyperion::GREEN, threshold[1u].asDouble());
|
colorTransform->_rgbGreenTransform.setWhitelevel(values[1u].asDouble());
|
||||||
_hyperion->setTransform(Hyperion::WHITELEVEL, Hyperion::BLUE, threshold[2u].asDouble());
|
colorTransform->_rgbBlueTransform .setWhitelevel(values[2u].asDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
sendSuccessReply();
|
sendSuccessReply();
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"required": true,
|
"required": true,
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"id" : {
|
||||||
|
"type" : "string",
|
||||||
|
"required" : false
|
||||||
|
},
|
||||||
"saturationGain" : {
|
"saturationGain" : {
|
||||||
"type" : "double",
|
"type" : "double",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
|
@ -160,7 +160,7 @@ void JsonConnection::clearAll()
|
|||||||
parseReply(reply);
|
parseReply(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonConnection::setTransform(double * saturation, double * value, ColorTransformValues *threshold, ColorTransformValues *gamma, ColorTransformValues *blacklevel, ColorTransformValues *whitelevel)
|
void JsonConnection::setTransform(std::string * transformId, 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,11 @@ void JsonConnection::setTransform(double * saturation, double * value, ColorTran
|
|||||||
command["command"] = "transform";
|
command["command"] = "transform";
|
||||||
Json::Value & transform = command["transform"];
|
Json::Value & transform = command["transform"];
|
||||||
|
|
||||||
|
if (transformId != nullptr)
|
||||||
|
{
|
||||||
|
transform["id"] = *transformId;
|
||||||
|
}
|
||||||
|
|
||||||
if (saturation != nullptr)
|
if (saturation != nullptr)
|
||||||
{
|
{
|
||||||
transform["saturationGain"] = *saturation;
|
transform["saturationGain"] = *saturation;
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// @note Note that providing a NULL will leave the settings on the server unchanged
|
/// @note Note that providing a NULL will leave the settings on the server unchanged
|
||||||
///
|
///
|
||||||
|
/// @param transformId The identifier of the transform to set
|
||||||
/// @param saturation The HSV saturation gain
|
/// @param saturation The HSV saturation gain
|
||||||
/// @param value The HSV value gain
|
/// @param value The HSV value gain
|
||||||
/// @param threshold The threshold
|
/// @param threshold The threshold
|
||||||
@ -84,6 +85,7 @@ public:
|
|||||||
/// @param whitelevel The whitelevel
|
/// @param whitelevel The whitelevel
|
||||||
///
|
///
|
||||||
void setTransform(
|
void setTransform(
|
||||||
|
std::string * transformId,
|
||||||
double * saturation,
|
double * saturation,
|
||||||
double * value,
|
double * value,
|
||||||
ColorTransformValues * threshold,
|
ColorTransformValues * threshold,
|
||||||
|
@ -45,6 +45,7 @@ int main(int argc, char * argv[])
|
|||||||
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "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");
|
||||||
|
StringParameter & argId = parameters.add<StringParameter> ('q', "qualifier" , "Identifier(qualifier) of the transform to set");
|
||||||
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "Set the HSV saturation gain of the leds");
|
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");
|
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)");
|
||||||
@ -83,6 +84,7 @@ 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 << " " << argId.usageLine() << std::endl;
|
||||||
std::cerr << " " << argSaturation.usageLine() << std::endl;
|
std::cerr << " " << argSaturation.usageLine() << std::endl;
|
||||||
std::cerr << " " << argValue.usageLine() << std::endl;
|
std::cerr << " " << argValue.usageLine() << std::endl;
|
||||||
std::cerr << " " << argThreshold.usageLine() << std::endl;
|
std::cerr << " " << argThreshold.usageLine() << std::endl;
|
||||||
@ -119,9 +121,11 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
else if (colorTransform)
|
else if (colorTransform)
|
||||||
{
|
{
|
||||||
|
std::string transId;
|
||||||
double saturation, value;
|
double saturation, value;
|
||||||
ColorTransformValues threshold, gamma, blacklevel, whitelevel;
|
ColorTransformValues threshold, gamma, blacklevel, whitelevel;
|
||||||
|
|
||||||
|
if (argId.isSet()) transId = argId.getValue();
|
||||||
if (argSaturation.isSet()) saturation = argSaturation.getValue();
|
if (argSaturation.isSet()) saturation = argSaturation.getValue();
|
||||||
if (argValue.isSet()) value = argValue.getValue();
|
if (argValue.isSet()) value = argValue.getValue();
|
||||||
if (argThreshold.isSet()) threshold = argThreshold.getValue();
|
if (argThreshold.isSet()) threshold = argThreshold.getValue();
|
||||||
@ -130,6 +134,7 @@ int main(int argc, char * argv[])
|
|||||||
if (argWhitelevel.isSet()) whitelevel = argWhitelevel.getValue();
|
if (argWhitelevel.isSet()) whitelevel = argWhitelevel.getValue();
|
||||||
|
|
||||||
connection.setTransform(
|
connection.setTransform(
|
||||||
|
argId.isSet() ? &transId : nullptr,
|
||||||
argSaturation.isSet() ? &saturation : nullptr,
|
argSaturation.isSet() ? &saturation : nullptr,
|
||||||
argValue.isSet() ? &value : nullptr,
|
argValue.isSet() ? &value : nullptr,
|
||||||
argThreshold.isSet() ? &threshold : nullptr,
|
argThreshold.isSet() ? &threshold : nullptr,
|
||||||
|
Loading…
Reference in New Issue
Block a user