Templated blur implementation + specializations for color_rgb(a)
This commit is contained in:
parent
f193ddf41d
commit
80e8c59a1e
2 changed files with 69 additions and 38 deletions
|
|
@ -3,9 +3,51 @@
|
||||||
#include <psemek/gfx/pixmap.hpp>
|
#include <psemek/gfx/pixmap.hpp>
|
||||||
#include <psemek/pcg/seamless.hpp>
|
#include <psemek/pcg/seamless.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace psemek::pcg
|
namespace psemek::pcg
|
||||||
{
|
{
|
||||||
|
|
||||||
gfx::basic_pixmap<float> blur(gfx::basic_pixmap<float> const & p, int size, float sigma, seamless_tag);
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<float> gauss_coeffs(int size, float sigma);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
gfx::basic_pixmap<T> blur(gfx::basic_pixmap<T> const & p, int size, float sigma, seamless_tag)
|
||||||
|
{
|
||||||
|
gfx::basic_pixmap<T> res({p.width(), p.height()}, T{});
|
||||||
|
|
||||||
|
auto c = detail::gauss_coeffs(size, sigma);
|
||||||
|
|
||||||
|
for (std::size_t y = 0; y < p.height(); ++y)
|
||||||
|
{
|
||||||
|
for (std::size_t x = 0; x < p.width(); ++x)
|
||||||
|
{
|
||||||
|
for (int j = - size; j <= size; ++j)
|
||||||
|
{
|
||||||
|
for (int i = - size; i <= size; ++i)
|
||||||
|
{
|
||||||
|
int ix = (x + i);
|
||||||
|
while (ix < 0) ix += p.width();
|
||||||
|
if (static_cast<std::size_t>(ix) >= p.width()) ix = ix % p.width();
|
||||||
|
|
||||||
|
int iy = (y + j);
|
||||||
|
while (iy < 0) iy += p.height();
|
||||||
|
if (static_cast<std::size_t>(iy) >= p.height()) iy = iy % p.height();
|
||||||
|
|
||||||
|
res(x, y) += p(ix, iy) * c[i + size] * c[j + size];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::pixmap_rgb blur(gfx::pixmap_rgb const & p, int size, float sigma, seamless_tag);
|
||||||
|
gfx::pixmap_rgba blur(gfx::pixmap_rgba const & p, int size, float sigma, seamless_tag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <psemek/pcg/blur.hpp>
|
#include <psemek/pcg/blur.hpp>
|
||||||
|
#include <psemek/gfx/color.hpp>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -6,7 +7,10 @@
|
||||||
namespace psemek::pcg
|
namespace psemek::pcg
|
||||||
{
|
{
|
||||||
|
|
||||||
static std::vector<float> gauss_coeffs(int size, float sigma)
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<float> gauss_coeffs(int size, float sigma)
|
||||||
{
|
{
|
||||||
std::vector<float> res(2 * size + 1);
|
std::vector<float> res(2 * size + 1);
|
||||||
float sum = 0.f;
|
float sum = 0.f;
|
||||||
|
|
@ -21,35 +25,20 @@ namespace psemek::pcg
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::basic_pixmap<float> blur(gfx::basic_pixmap<float> const & p, int size, float sigma, seamless_tag)
|
}
|
||||||
|
|
||||||
|
gfx::pixmap_rgb blur(gfx::pixmap_rgb const & p, int size, float sigma, seamless_tag)
|
||||||
{
|
{
|
||||||
gfx::basic_pixmap<float> res({p.width(), p.height()}, 0.f);
|
auto converted = util::map([](gfx::color_rgb const & c){ return gfx::to_colorf(c); }, p);
|
||||||
|
converted = blur(converted, size, sigma, seamless);
|
||||||
|
return util::map([](geom::vector<float, 3> const & c){ return gfx::to_coloru8(c); }, converted);
|
||||||
|
}
|
||||||
|
|
||||||
auto c = gauss_coeffs(size, sigma);
|
gfx::pixmap_rgba blur(gfx::pixmap_rgba const & p, int size, float sigma, seamless_tag)
|
||||||
|
|
||||||
for (std::size_t y = 0; y < p.height(); ++y)
|
|
||||||
{
|
{
|
||||||
for (std::size_t x = 0; x < p.width(); ++x)
|
auto converted = util::map([](gfx::color_rgba const & c){ return gfx::to_colorf(c); }, p);
|
||||||
{
|
converted = blur(converted, size, sigma, seamless);
|
||||||
for (int j = - size; j <= size; ++j)
|
return util::map([](geom::vector<float, 4> const & c){ return gfx::to_coloru8(c); }, converted);
|
||||||
{
|
|
||||||
for (int i = - size; i <= size; ++i)
|
|
||||||
{
|
|
||||||
int ix = (x + i);
|
|
||||||
while (ix < 0) ix += p.width();
|
|
||||||
if (static_cast<std::size_t>(ix) >= p.width()) ix = ix % p.width();
|
|
||||||
|
|
||||||
int iy = (y + j);
|
|
||||||
while (iy < 0) iy += p.height();
|
|
||||||
if (static_cast<std::size_t>(iy) >= p.height()) iy = iy % p.height();
|
|
||||||
|
|
||||||
res(x, y) += p(ix, iy) * c[i + size] * c[j + size];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue