Skip to content

Instantly share code, notes, and snippets.

@kbob
Last active November 28, 2025 14:34
Show Gist options
  • Select an option

  • Save kbob/d2a7e0ffcdbb0dca089032491df1084f to your computer and use it in GitHub Desktop.

Select an option

Save kbob/d2a7e0ffcdbb0dca089032491df1084f to your computer and use it in GitHub Desktop.
Apply Knuth/Dockrey glitch function to BadApple
#!/usr/bin/env python
from itertools import chain, repeat
import numpy as np
from PIL import Image, ImageSequence
GIF_PATH = 'Bad.Apple!!.full.2116173.gif'
FRAME_COUNT = 3110
# BadApple is 20 frames/second. We can output a 20 FPS image sequence
# or we can repeat the BadApple frames and run the glitch at 60 FPS.
EMIT_60FPS = True
# If you only glitch 25% of the pixels, the video is easier to make out.
GLITCH_25 = True
# Matthew Dockrey's version of this
# https://clacks.link/@attoparsec/115590622107796156
# has X and Y reversed, decrements X offset
MIMIC_DOCKREY = True
SCROLL_VERTICALLY = MIMIC_DOCKREY
DECREMENT_OFFSET = MIMIC_DOCKREY
# very small t values are less interesting
MIN_T = 350
# At 20 FPS, animate the glitch faster
T_STEP_20FPS = 3
T_STEP_60FPS = 1
# Knuth's bitwise fractal (AoCP vol 4A)
# (((x ^ ~y) & ((x - 350) >> 3))**2 >> 12) & 1
def glitch(w, h, t):
x = np.arange(w)
y = np.arange(h)
if SCROLL_VERTICALLY:
l, r = y, ~x
o = y[:, np.newaxis] # reshape as column so broadcast will work
else:
l, r = ~y, x
o = x
m = 3 if GLITCH_25 else 1
bit = ((((np.bitwise_xor.outer(l, r) & (o - t) >> 3))**2 >> 12) & m) == 1
return bit
def print_array(name, a):
print(f'{name}: '
f'shape={a.shape} '
f'dtype={a.dtype} '
f'element={a[0, 0]}')
src_seq = ImageSequence.Iterator(Image.open(GIF_PATH))
t_seq = range(MIN_T, MIN_T + FRAME_COUNT, T_STEP_20FPS)
if EMIT_60FPS:
src_seq = chain.from_iterable(repeat(f, 3) for f in src_seq)
t_seq = range(MIN_T, MIN_T + 3 * FRAME_COUNT, T_STEP_60FPS)
if DECREMENT_OFFSET:
t_seq = reversed(t_seq)
dst_seq = []
for (t, src_im) in zip(t_seq, src_seq):
src = np.array(src_im)
bit = glitch(*src_im.size, t)
if src.shape[2:] == ():
# one color channel
mask = bit
elif src.shape[2:] == (4, ):
# four color channels
alpha = np.ones(bit.shape, dtype=bit.dtype)
mask = np.stack(3 * (bit, ) + (alpha, ), axis=-1)
else:
raise NotImplementedError(f'unexpected pixel shape {i=} {src.shape=}')
dst = src * ~mask + (255 - src) * mask
dst_im = Image.fromarray(dst)
dst_seq.append(dst_im)
dst_seq[0].save(
'test.png',
save_all=True,
append_images=dst_seq[1:],
duration=(1000 / 60 if EMIT_60FPS else 1000 / 20),
loop=0
)
# Follow this with
# ffmpeg -i test.png -pix_fmt yuv420p output.mp4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment