jfjoch_viewer: Add more color modes - white on black and 3 green schemes

This commit is contained in:
2026-01-30 11:03:52 +01:00
parent 8fd02c47d4
commit 12c8a45595
3 changed files with 70 additions and 8 deletions
+51 -6
View File
@@ -5,6 +5,26 @@
#include "ColorScale.h"
#include "JFJochException.h"
static inline float Clamp01(float x) {
return (x < 0.0f) ? 0.0f : (x > 1.0f ? 1.0f : x);
}
// Gamma-mapped green (recommended gamma = 0.7)
static inline rgb GreenGamma(float f, float gamma = 0.7f) {
f = Clamp01(f);
const float g = std::pow(f, gamma);
const uint8_t G = static_cast<uint8_t>(std::lround(255.0f * g));
return {.r = 0, .g = G, .b = 0};
}
// Asinh-mapped green (recommended k = 8.0)
static inline rgb GreenAsinh(float f, float k = 8.0f) {
f = Clamp01(f);
const float g = std::asinh(k * f) / std::asinh(k);
const uint8_t G = static_cast<uint8_t>(std::lround(255.0f * g));
return {.r = 0, .g = G, .b = 0};
}
float luminance(rgb input) {
return 0.2126f * input.r + 0.7152f * input.g + 0.0722f * input.b;
}
@@ -26,18 +46,43 @@ void ColorScale::CalcLUT() const {
const std::vector<rgb>* map = nullptr;
switch (current) {
case ColorScaleEnum::Viridis: map = &viridis_colormap; break;
case ColorScaleEnum::Heat: map = &heat_colormap; break;
case ColorScaleEnum::Indigo: map = &white_to_indigo_colormap; break;
case ColorScaleEnum::BW: map = &white_to_black_colormap; break;
case ColorScaleEnum::Heat: map = &heat_colormap;
break;
case ColorScaleEnum::Indigo: map = &white_to_indigo_colormap;
break;
case ColorScaleEnum::BW: map = &white_to_black_colormap;
break;
case ColorScaleEnum::WB: map = &black_to_white_colormap;
break;
case ColorScaleEnum::Green1:
case ColorScaleEnum::Green2:
map = nullptr;
break; // handled below
case ColorScaleEnum::Green3:
map = &green_colormap;
break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Color scale unknown");
}
for (size_t i = 0; i < kLutSize; ++i) {
const float f = static_cast<float>(i) / static_cast<float>(kLutSize - 1);
lut_[i] = Apply(f, *map);
if (current == ColorScaleEnum::Green1) {
for (size_t i = 0; i < kLutSize; ++i) {
const float f = static_cast<float>(i) / static_cast<float>(kLutSize - 1);
lut_[i] = GreenGamma(f, 0.7f);
}
} else if (current == ColorScaleEnum::Green2) {
for (size_t i = 0; i < kLutSize; ++i) {
const float f = static_cast<float>(i) / static_cast<float>(kLutSize - 1);
lut_[i] = GreenAsinh(f, 8.0f);
}
} else {
for (size_t i = 0; i < kLutSize; ++i) {
const float f = static_cast<float>(i) / static_cast<float>(kLutSize - 1);
lut_[i] = Apply(f, *map);
}
}
}
rgb ColorScale::Apply(float input, const std::vector<rgb> &map) {
+13 -1
View File
@@ -21,7 +21,11 @@ enum class ColorScaleEnum : int {
Viridis = 0,
Heat = 1,
Indigo = 2,
BW = 3
BW = 3,
WB = 4,
Green1 = 5,
Green2 = 6,
Green3 = 7
};
enum class ColorScaleSpecial {
@@ -47,6 +51,14 @@ class ColorScale {
{255, 255, 255}, {0, 0, 0}
};
const std::vector<rgb> black_to_white_colormap = {
{0, 0, 0}, {255, 255, 255}
};
const std::vector<rgb> green_colormap = {
{0, 0, 0}, {0, 255, 0}
};
ColorScaleEnum current = ColorScaleEnum::Indigo;
rgb gap = {.r = 190, .g = 190, .b = 190}; // Gray
@@ -25,7 +25,12 @@ JFJochViewerToolbarDisplay::JFJochViewerToolbarDisplay(QWidget *parent)
color_map_select->addItem("Viridis", static_cast<int>(ColorScaleEnum::Viridis));
color_map_select->addItem("Heat", static_cast<int>(ColorScaleEnum::Heat));
color_map_select->addItem("Indigo", static_cast<int>(ColorScaleEnum::Indigo));
color_map_select->addItem("B/W", static_cast<int>(ColorScaleEnum::BW));
color_map_select->addItem("Black on white", static_cast<int>(ColorScaleEnum::BW));
color_map_select->addItem("White on black", static_cast<int>(ColorScaleEnum::WB));
color_map_select->addItem("Green (gamma)", static_cast<int>(ColorScaleEnum::Green1));
color_map_select->addItem("Green (asinh)", static_cast<int>(ColorScaleEnum::Green2));
color_map_select->addItem("Green (linear)", static_cast<int>(ColorScaleEnum::Green3));
color_map_select->setCurrentIndex(static_cast<int>(ColorScaleEnum::Indigo));
addWidget(color_map_select);