Files
effector/src/effects/tileswap.hpp
T
SiandClaude Opus 5.5 1b30a079e6 Add Tile swap, a video effect built from the source images
Tile swap lays tiles cut from the photographs over the canvas as Tiles
does, in a grid, in bricks or scattered, and swaps each one for another
cut at a moment of its own, so the mosaic keeps changing piece by piece.
The layout stays put for the whole clip; what a tile shows depends only
on the tile and how many times it has swapped, counted round the clip, so
it holds still between swaps and the clip loops without a jump. On the
command line it is -e tileswap with --tileswap-rate and the rest.

VideoEffect learns a second kind: an effect that answers needsSources()
writes compose() instead of animate(), and the base then takes no crop,
only the one seed, so it sees the photographs when it leads the chain and
the stage before it otherwise. Transforms render exactly as before. The
tile cutting and painting move out of tiles.cpp into tile_plan.hpp for
both effects to share; Tiles renders byte for byte as before. Version
0.8.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:22:26 +02:00

32 lines
1.3 KiB
C++

#pragma once
#include "effects/video_effect.hpp"
namespace effector {
// The tiles effect in motion: the canvas is laid with tiles cut from the
// source images, and each tile is swapped for another cut, at a moment of its
// own, so the mosaic keeps changing piece by piece.
//
// The video effect built from the sources rather than transforming its input:
// it answers needsSources() and writes compose(). The layout is drawn from
// at.steady() and stays put; what a tile shows depends only on the tile and
// how many times it has swapped, so it holds still between its swaps.
class TileSwapEffect : public VideoEffect {
public:
std::string name() const override { return "tileswap"; }
std::string title() const override { return "Tile swap"; }
std::string description() const override {
return "Lays tiles cut from the source images over the canvas, as Tiles does, and swaps "
"each one for another cut at a moment of its own.";
}
const std::vector<ParamSpec>& params() const override;
bool needsSources() const override { return true; }
protected:
Image compose(const std::vector<Image>& sources, int width, int height,
const ParamValues& values, const Moment& at) const override;
};
} // namespace effector