78 lines
2.0 KiB
C++
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++;
|
|
//}
|
|
}
|