Files
test/sexp_effects/effects/blend.sexp
gilesb 6ceaa37ab6 Add composable ASCII art with per-cell effects and explicit effect loading
Implements ascii_fx_zone effect that allows applying arbitrary sexp effects
to each character cell via cell_effect lambdas. Each cell is rendered as a
small image that effects can operate on.

Key changes:
- New ascii_fx_zone effect with cell_effect parameter for per-cell transforms
- Zone context (row, col, lum, sat, hue, etc.) available in cell_effect lambdas
- Effects are now loaded explicitly from recipe declarations, not auto-loaded
- Added effects_registry to plan for explicit effect dependency tracking
- Updated effect definition syntax across all sexp effects
- New run_staged.py for executing staged recipes
- Example recipes demonstrating alternating rotation and blur/rgb_split patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 21:58:05 +00:00

55 lines
2.1 KiB
Common Lisp

;; Blend effect - combines two video streams
;; Multi-input effect: uses frame-a and frame-b
;; Params:
;; mode - blend mode (add, multiply, screen, overlay, difference, lighten, darken, alpha)
;; opacity - blend amount (0-1)
;; resize-mode - how to resize frame-b to match frame-a (fit, crop, stretch)
;; priority - which dimension takes priority (width, height)
;; pad-color - color for padding in fit mode [r g b]
(define-effect blend
:params (
(mode :type string :default "overlay")
(opacity :type float :default 0.5)
(priority :type string :default "width")
(list :type string :default 0 0 0)
)
)
(let [a frame-a
a-w (width a)
a-h (height a)
b-raw frame-b
b-w (width b-raw)
b-h (height b-raw)
;; Calculate scale based on resize mode and priority
scale-w (/ a-w b-w)
scale-h (/ a-h b-h)
scale (if (= resize-mode "stretch")
1 ;; Will use explicit dimensions
(if (= resize-mode "crop")
(max scale-w scale-h) ;; Scale to cover, then crop
(if (= priority "width")
scale-w
scale-h)))
;; For stretch, use target dimensions directly
new-w (if (= resize-mode "stretch") a-w (round (* b-w scale)))
new-h (if (= resize-mode "stretch") a-h (round (* b-h scale)))
;; Resize b
b-resized (resize b-raw new-w new-h "linear")
;; Handle fit (pad) or crop to exact size
b (if (= resize-mode "crop")
;; Crop to center
(let [cx (/ (- new-w a-w) 2)
cy (/ (- new-h a-h) 2)]
(crop b-resized cx cy a-w a-h))
(if (and (= resize-mode "fit") (or (!= new-w a-w) (!= new-h a-h)))
;; Pad to center
(let [pad-x (/ (- a-w new-w) 2)
pad-y (/ (- a-h new-h) 2)
canvas (make-image a-w a-h pad-color)]
(paste canvas b-resized pad-x pad-y))
b-resized))]
(if (= mode "alpha")
(blend-images a b opacity)
(blend-images a (blend-mode a b mode) opacity)))