texproc/fix_colors.cpp
2025-01-19 19:50:30 +01:00

78 lines
2.0 KiB
C++

#include "fix_colors.hpp"
#include <algorithm>
#include <vector>
#define ALPHA_THRESHOLD 127
struct Coord {
int x, y;
};
static ColorRGB FindClosestOpaque(const Image& image, size_t x, size_t y, const std::vector<Coord>& kernel) {
for (const Coord& c : kernel) {
int cx = x + c.x;
int cy = y + c.y;
if (cx < 0 || cx >= image.GetWidth() || cy < 0 || cy >= image.GetHeight()) {
continue;
}
const ColorRGBA& pixel = image.At(cx, cy);
if (pixel.a >= ALPHA_THRESHOLD) {
return pixel.rgb;
}
}
return { 255, 0, 0 };
}
void FixColors::Fix(const Image& src, Image& dst, float max_dist) {
std::vector<Coord> kernel;
for (int y = -max_dist; y <= max_dist; y++) {
for (int x = -max_dist; x <= max_dist; x++) {
kernel.push_back({ x, y });
}
}
//kernel.erase(std::remove_if(kernel.begin(), kernel.end(), [max_dist](const Coord& c) {
// return c.x * c.x + c.y * c.y > max_dist * max_dist;
//}), kernel.end());
std::sort(kernel.begin(), kernel.end(), [](const Coord& a, const Coord& b) {
return a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;
});
for (size_t y = 0; y < src.GetHeight(); y++) {
for (size_t x = 0; x < src.GetWidth(); x++) {
const ColorRGBA& pixel_src = src.At(x, y);
ColorRGBA& pixel_dst = dst.At(x, y);
pixel_dst.a = pixel_src.a;
if (pixel_src.a < ALPHA_THRESHOLD) {
pixel_dst.rgb = FindClosestOpaque(src, x, y, kernel);
}
else {
pixel_dst.rgb = pixel_src.rgb;
}
//pixel_dst.a = 255;
}
}
//size_t i = 0;
//for (const Coord& c : kernel) {
// ColorRGBA& pixel = image.At(c.x + 40, c.y + 40);
//
// uint8_t intensity = i * 255 / kernel.size();
//
// pixel.rgb = { intensity, 0, 0 };
// pixel.a = 255;
// i++;
//}
}