Win32 API、具体的にはShell lightweight utility functions(Microsoft Docs)のColorHLSToRGB
関数、ColotRGBToHLS
関数を使用したHLS色空間クラスです。
std::clamp
を使っているので動作環境をC++20としていますが、適当に書き換えればC++17以前にも対応できます。
ソースコード
// win32_hls_color.hpp // 動作確認環境:C++ 20 #include <algorithm> #include <stdexcept> #include <tuple> #include <shlwapi.h> class win32_hls_color { private: uint16_t _h; uint16_t _l; uint16_t _s; public: static const uint16_t h_min = 0; static const uint16_t h_max = 240; static const uint16_t l_min = 0; static const uint16_t l_max = 240; static const uint16_t s_min = 0; static const uint16_t s_max = 240; static constexpr win32_hls_color min() noexcept { return from_hls_nochecked(h_min, l_min, s_min); } static constexpr win32_hls_color max() noexcept { return from_hls_nochecked(h_max, l_max, s_max); } constexpr win32_hls_color() noexcept : _h(), _l(), _s() {} constexpr win32_hls_color(const win32_hls_color& source) noexcept : _h(source._h), _l(source._l), _s(source._s) {} constexpr win32_hls_color(win32_hls_color&& source) noexcept : _h(source._h), _l(source._l), _s(source._s) {} constexpr uint16_t get_h() const noexcept { return _h; } constexpr uint16_t get_l() const noexcept { return _l; } constexpr uint16_t get_s() const noexcept { return _s; } constexpr void get_hsl(uint16_t& h, uint16_t l, uint16_t& s) const noexcept { h = _h; l = _l; s = _s; } constexpr std::tuple<uint16_t, uint16_t, uint16_t> get_hls_tuple() const noexcept { return { _h, _l, _s }; } constexpr void set_h(uint16_t h) { if (!(h_min <= h && h <= h_max)) { throw std::range_error(nullptr); } _h = h; } constexpr void set_l(uint16_t l) { if (!(l_min <= l && l <= l_max)) { throw std::range_error(nullptr); } _l = l; } constexpr void set_s(uint16_t s) { if (!(s_min <= s && s <= s_max)) { throw std::range_error(nullptr); } _s = s; } constexpr void set_hls(uint16_t h, uint16_t s, uint16_t l) { set_h(h); set_l(l); set_s(s); } constexpr void set_hls_tuple(std::tuple<uint16_t, uint16_t, uint16_t> tuple) { set_h(std::get<0>(tuple)); set_l(std::get<1>(tuple)); set_s(std::get<2>(tuple)); } constexpr void set_h_clamped(uint16_t h) noexcept { _h = std::clamp(h, h_min, h_max); } constexpr void set_l_clamped(uint16_t l) noexcept { _l = std::clamp(l, l_min, l_max); } constexpr void set_s_clamped(uint16_t s) noexcept { _s = std::clamp(s, s_min, s_max); } constexpr void set_hls_clamped(uint16_t h, uint16_t s, uint16_t l) noexcept { set_h_clamped(h); set_l_clamped(l); set_s_clamped(s); } constexpr void set_hls_tuple_clamped(std::tuple<uint16_t, uint16_t, uint16_t> tuple) noexcept { set_h_clamped(std::get<0>(tuple)); set_l_clamped(std::get<1>(tuple)); set_s_clamped(std::get<2>(tuple)); } uint32_t to_rgb() noexcept { return ColorHLSToRGB(_h, _l, _s); } static win32_hls_color from_rgb(uint32_t rgb) noexcept { uint16_t h, l, s; ColorRGBToHLS(rgb, &h, &l, &s); return from_hls_nochecked(h, l, s); } static win32_hls_color from_rgb(uint8_t r, uint8_t g, uint8_t b) noexcept { return from_rgb(RGB(r, g, b)); } static constexpr win32_hls_color from_hls(uint16_t h, uint16_t l, uint16_t s) { win32_hls_color color; color.set_h(h); color.set_l(l); color.set_s(s); return color; } static constexpr win32_hls_color from_hls_clamped(uint16_t h, uint16_t l, uint16_t s) noexcept { win32_hls_color color; color.set_h_clamped(h); color.set_l_clamped(l); color.set_s_clamped(s); return color; } static constexpr win32_hls_color from_hls(std::initializer_list<uint16_t> hls) { auto i = hls.begin(); win32_hls_color color; if (i != hls.end()) { color.set_h(*i++); if (i != hls.end()) { color.set_l(*i++); if (i != hls.end()) { color.set_s(*i); } } } return color; } static constexpr win32_hls_color from_hls_clamped(std::initializer_list<uint16_t> hls) noexcept { auto i = hls.begin(); win32_hls_color color; if (i != hls.end()) { color.set_h_clamped(*i++); if (i != hls.end()) { color.set_l_clamped(*i++); if (i != hls.end()) { color.set_s_clamped(*i); } } } return color; } private: static constexpr win32_hls_color from_hls_nochecked(uint16_t h, uint16_t l, uint16_t s) noexcept { win32_hls_color color; color._h = h; color._l = l; color._s = s; return color; } };
サンプルコード
#pragma comment(lib, "shlwapi.lib") #define STRICT #define NOMINMAX #include <Windows.h> #include <Shlwapi.h> #include "win32_hls_color.hpp" int main() { auto red = win32_hls_color::from_rgb(255, 0, 0); auto green = win32_hls_color::from_rgb(0, 255, 0); auto blue = win32_hls_color::from_rgb(0, 0, 255); auto yellow = win32_hls_color::from_rgb(255, 255, 0); auto magenta = win32_hls_color::from_rgb(255, 0, 255); auto cyan = win32_hls_color::from_rgb(0, 255, 255); auto black = win32_hls_color::from_rgb(0, 0, 0); auto white = win32_hls_color::from_rgb(255, 255, 255); // name { H , S , L } // red { 0, 120, 240} // green { 80, 120, 240} // blue {160, 120, 240} // yellow { 40, 120, 240} // magenta {200, 120, 240} // cyan {120, 120, 240} // black {160, 0, 0} // white {160, 240, 0} }