BrushCue Example: Glitch Filter Animation¶

Open In Colab

You can use this tool online at https://www.brushcue.com/tools/glitch-filter-animation

In [ ]:
!pip install brushcue
In [1]:
import brushcue as bc


@bc.brushcue_fn
def frame(time):
    input_image = bc.Composition.monet_women_with_parasol()
    green_channel = input_image.linear_transform(
        0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0
    )
    red_channel = input_image.linear_transform(
        1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0
    )
    displacement = 32.0
    source_bounds = input_image.bounds()
    overlap = 2.0
    horizontal_crop_padding = bc.Float.min(overlap, (source_bounds.width() / 4.0))
    effective_displacement = bc.Float.min(
        displacement,
        bc.Float.max(0.0, ((source_bounds.width() / 2.0) - horizontal_crop_padding)),
    )
    glitch_envelope = 0.25 + (0.75 * ((bc.Float.pi() * time) / 0.8).sin().abs())
    red_x = (effective_displacement * glitch_envelope) * (
        0.75 + (0.25 * (time * 45.0).sin().abs())
    )
    red_y = (4.0 * glitch_envelope) * (time * 38.0).sin()
    red_offset = bc.Transform2.identity().translation(
        bc.Vector2f.from_components(red_x, red_y)
    )
    blue_channel = input_image.linear_transform(
        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
    )
    blue_x = (((-1.0) * effective_displacement) * glitch_envelope) * (
        0.75 + (0.25 * (time * 41.0).cos().abs())
    )
    blue_y = ((-4.0) * glitch_envelope) * (time * 35.0).cos()
    blue_offset = bc.Transform2.identity().translation(
        bc.Vector2f.from_components(blue_x, blue_y)
    )
    combined = green_channel.blend_add(red_channel, red_offset).blend_add(
        blue_channel, blue_offset
    )
    horizontal_crop = effective_displacement + horizontal_crop_padding
    return combined.crop(
        bc.Bounds2f.from_x_y_width_height(
            horizontal_crop,
            6.0,
            (source_bounds.width() - (horizontal_crop * 2.0)),
            (source_bounds.height() - 12.0),
        )
    )


graph = bc.Sequence.graph(0.8, frame)

ctx = bc.Context()
sequence = graph.execute(ctx)
# Render `sequence` to a video file as needed.
[wgpu] using backend Metal — adapter 'Apple M5' (IntegratedGpu), driver ''