Files
effector/src/effects/overlay.hpp
T
SiandClaude Opus 5 e2252ecd30 Add an image overlay effect
Lays a single picture from disk over its input: fitted, filled, stretched,
left at its own size or tiled, centred or pinned to the top left corner,
nudged by an offset and mixed in by its opacity.

The file it needs is a new kind of param, Path, so the interface shows a
chooser and the CLI takes a file name, both without knowing an overlay
exists. Projects write it relative to their own folder, as they do a
source, and Image::load can now hand back the alpha channel instead of
flattening it onto white, so a cut-out PNG keeps its cut-out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 19:31:09 +02:00

46 lines
1.7 KiB
C++

#pragma once
#include <cstdint>
#include <mutex>
#include <string>
#include <vector>
#include "core/effect.hpp"
namespace effector {
// Lays one picture from disk over its input: a logo, a texture, a frame. The
// overlay is fitted to the canvas in the chosen way, placed from the top left
// or from the centre, nudged by an offset and mixed in by its opacity. Like the
// blur it needs no source images of its own, so it can lead a chain; given
// sources it fills the canvas from a randomly chosen one first.
class OverlayEffect : public Effect {
public:
std::string name() const override { return "overlay"; }
std::string title() const override { return "Image overlay"; }
std::string description() const override {
return "Lays a single image from disk over its input, fitted to the canvas, centred or "
"not, nudged by an offset and mixed in by its opacity.";
}
const std::vector<ParamSpec>& params() const override;
bool needsSources() const override { return false; }
Image render(const std::vector<Image>& sources, int width, int height, Rng& rng,
const ParamValues& values) const override;
private:
// The same file is re-read on every param change otherwise, and a render is
// a keystroke away in the interface. Renders can overlap, so it is guarded.
// Returns the decoded file and its alpha, reading it only when the path
// differs from the one already held.
void loadOverlay(const std::string& path, Image& image,
std::vector<std::uint8_t>& alpha) const;
mutable std::mutex cacheMutex_;
mutable std::string cachedPath_;
mutable Image cached_;
mutable std::vector<std::uint8_t> cachedAlpha_;
};
} // namespace effector