Blur's box blur moves to effects/box_blur.hpp so both share it; Blur renders exactly as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
2.1 KiB
C++
51 lines
2.1 KiB
C++
#include "effects/blur.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
#include "effects/box_blur.hpp"
|
|
#include "effects/source_fill.hpp"
|
|
|
|
namespace effector {
|
|
|
|
const std::vector<ParamSpec>& BlurEffect::params() const {
|
|
static const std::vector<ParamSpec> specs = {
|
|
ParamSpec::makeInt("radius", "Radius", 8, 1, 256,
|
|
"Half width in pixels of the blur window."),
|
|
ParamSpec::makeInt("passes", "Passes", 2, 1, 8,
|
|
"How often the box blur is repeated; more passes look more gaussian."),
|
|
ParamSpec::makeChoice("direction", "Direction", "both", {"both", "horizontal", "vertical"},
|
|
"Axis the blur is applied along."),
|
|
ParamSpec::makeBool("first_source", "Use the first image", false,
|
|
"Always blur the first source instead of picking one at random."),
|
|
};
|
|
return specs;
|
|
}
|
|
|
|
Image BlurEffect::render(const std::vector<Image>& sources, int width, int height, Rng& rng,
|
|
const ParamValues& values) const {
|
|
if (width < 1 || height < 1) throw EffectError("Canvas size must be at least 1x1 pixels.");
|
|
|
|
const int radius = static_cast<int>(std::max(1L, paramInt(values, "radius", 8)));
|
|
const int passes = static_cast<int>(std::max(1L, paramInt(values, "passes", 2)));
|
|
const std::string direction = paramChoice(values, "direction", "both");
|
|
const bool firstSource = paramBool(values, "first_source", false);
|
|
|
|
Image canvas(width, height);
|
|
if (!sources.empty()) {
|
|
// Every random value is drawn here, before any threading, so that a
|
|
// seed always gives the same image.
|
|
const std::size_t index = firstSource ? 0 : rng.below(sources.size() - 1);
|
|
const Image& src = sources[index];
|
|
const int sx = static_cast<int>(rng.inRange(0, std::max(0, src.width() - width)));
|
|
const int sy = static_cast<int>(rng.inRange(0, std::max(0, src.height() - height)));
|
|
fillFromSource(canvas, src, sx, sy);
|
|
}
|
|
|
|
boxBlur(canvas, radius, passes, direction);
|
|
|
|
return canvas;
|
|
}
|
|
|
|
} // namespace effector
|