WIP add color

This commit is contained in:
Bart Beumer 2025-11-11 19:56:39 +00:00
parent 63be32de7c
commit 6cd04636c1
2 changed files with 150 additions and 4 deletions

View File

@ -10,6 +10,7 @@
#include <bmrshared/request_handler_interface.hpp>
#include <bmrshared/directory_request_handler.hpp>
#include <bmrshared/request_response.hpp>
#include <bmrshared/color.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/gil/image.hpp>
#include <boost/gil/image_view.hpp>
@ -155,16 +156,23 @@ void fractal(
constexpr int max_iterations = 255;
boost::gil::gray8_image_t image(pixel_width,pixel_height);
boost::gil::rgb8_image_t image(pixel_width,pixel_height);
auto view = boost::gil::view(image);
boost::gil::fill_pixels(view, boost::gil::gray8_pixel_t(0));
boost::gil::fill_pixels(view, boost::gil::rgb8_pixel_t(0));
auto painter = [&](int x, int y, int num_iter) -> void
{
if(x >= 0 && y >= 0 && x < pixel_width && y < pixel_height)
{
bmrshared::color c({.h=(num_iter*5)%360,.s=(0.5+(num_iter/200.0)), .v=1.0});
auto crgb = c.rgb();
uint8_t r = crgb.r * 255;
uint8_t g = crgb.g * 255;
uint8_t b = crgb.b * 255;
const auto iter = view.at({x, y});
boost::gil::color_convert(boost::gil::gray8_pixel_t(num_iter), *iter);
boost::gil::color_convert(boost::gil::rgb8_pixel_t(r,g,b), *iter);
}
};
@ -245,7 +253,7 @@ int main(int argc, char **argv)
std::vector<std::jthread> threads;
while(threads.size() < 16)
while(threads.size() < 4)
{
threads.emplace_back([&ioc]{ioc.run();});
}

View File

@ -0,0 +1,138 @@
// GNU Lesser General Public License v3.0
// Copyright (c) 2023 Bart Beumer <bart@4beumer.nl>
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License v3.0 as published by
// the Free Software Foundation.
//
#pragma once
#include <cmath>
#include <optional>
#include <utility>
namespace bmrshared
{
class color
{
public:
struct color_hsv
{
double h;
double s;
double v;
};
struct color_rgb
{
double r;
double g;
double b;
};
color() = delete;
~color() = default;
constexpr color(const color&) = default;
constexpr color(color&&) = default;
constexpr color& operator=(const color&) = default;
constexpr color& operator=(color&&) = default;
constexpr color(const color_hsv& c)
: m_rgb()
, m_hsv(c)
{}
constexpr color(const color_rgb& c)
: m_rgb(c)
, m_hsv()
{}
constexpr const color_rgb& rgb() const
{
if (!m_rgb)
{
m_rgb = calculate_rgb(*m_hsv);
}
return *m_rgb;
}
constexpr const color_hsv& hsv() const
{
if (!m_hsv)
{
m_hsv = calculate_hsv(*m_rgb);
}
return *m_hsv;
}
private:
static constexpr color_hsv calculate_hsv(const color_rgb& c)
{
color_hsv r{.h = 0.0, .s = 0.0, .v = 0.0};
double min = std::min(c.r, std::min(c.g,c.b));
r.v = std::max(c.r, std::max(c.g,c.b));
double delta = r.v - min;
r.s = (r.v <= 0.0) ? 0.0 : (delta / r.v);
if (r.s <= 0.0)
{
r.h = 0.0;
}
else
{
if (c.r == r.v)
{
r.h = (c.g - c.b) / delta;
}
else if (c.g == r.v)
{
r.h = 2.0 + (c.b - c.r) / delta;
}
else if (c.b == r.v)
{
r.h = 4.0 + (c.r - c.g) / delta;
}
r.h*=60.0;
if (r.h < 0.0)
{
r.h +=360.0;
}
}
return r;
}
static constexpr color_rgb calculate_rgb(const color_hsv& in)
{
double C = in.s * in.v;
double X = C*(1-std::fabs(std::fmod(in.h/60.0, 2)-1));
double m = in.v-C;
color_rgb result{.r = 0.0, .g = 0.0, .b = 0.0};
if(in.h >= 0.0 && in.h < 60.0){
result = {.r = C, .g = X, .b = 0.0};
}
else if(in.h >= 60.0 && in.h < 120.0){
result = {.r = X, .g = C, . b = 0.0};
}
else if(in.h >= 120.0 && in.h < 180.0){
result = {.r = 0.0, .g = C, .b = X};
}
else if(in.h >= 180.0 && in.h < 240.0){
result = {.r = 0.0, .g = X, .b = C};
}
else if(in.h >= 240.0 && in.h < 300.0){
result = {.r = X, .g = 0.0, .b = C};
}
else{
result = {.r = C, .g = 0.0, .b = X};
}
result.r+=m;
result.g+=m;
result.b+=m;
return result;
}
mutable std::optional<color_rgb> m_rgb;
mutable std::optional<color_hsv> m_hsv;
};
}