Skip to content

Instantly share code, notes, and snippets.

@ryukinix
Last active September 26, 2021 06:34
Show Gist options
  • Save ryukinix/0ade7bf523713b5bc1b0723755ef4ead to your computer and use it in GitHub Desktop.
Save ryukinix/0ade7bf523713b5bc1b0723755ef4ead to your computer and use it in GitHub Desktop.
Fauux Mystery Decoder for 2021 puzzle
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright © 2021 Manoel Vilela
#
# @project: Fauux Mystery Decoder for 2021 puzzle
# @author: Manoel Vilela
# @email: [email protected]
#
"""Ensure you have installed:
pip install numpy av Pillow
Execute this script after download blue.mov, green.mov and red.mov files from
fauux.neocities.org website.
This is only a part of the puzzle.
Good luck.
"""
import typing as T
import av
import numpy as np
from av.video.frame import VideoFrame
from PIL import Image
files_by_window_size = {
"blue.mov": 8,
"green.mov": 16,
"red.mov": 32
}
def address_windowed(idx, x_shape, y_shape, window):
x = window * (idx // (x_shape // window))
y = window * (idx % (y_shape // window))
return x, y
def video_to_array_frames(video: str) -> T.List[np.array]:
video = av.open(video)
frames = []
for packet in video.demux():
for frame in packet.decode():
if isinstance(frame, VideoFrame):
img = frame.to_image() # PIL/Pillow image
arr = np.asarray(img) # numpy array
frames.append(arr)
return frames
def blend_arrays(arrays: T.List[np.array], window: int) -> np.array:
array_shape = arrays[0].shape
x_shape, y_shape, _ = array_shape
array_base = np.zeros(array_shape)
for idx, array in enumerate(arrays):
x, y = address_windowed(idx, x_shape, y_shape, window)
x_w = x + window
y_w = y + window
array_base[x:x_w, y:y_w, :] = array[x:x_w, y:y_w, :]
return array_base
def red_blend_arrays(arrays: T.List[np.array]) -> np.array:
array_shape = (512, 512, 3)
x_shape, y_shape, _ = array_shape
array_base = np.zeros(array_shape)
window = 32
for idx, array in enumerate(arrays):
x, y = address_windowed(idx, x_shape, y_shape, window)
x_w = x + window
y_w = y + window
array_base[x:x_w, y:y_w, :] = array
return array_base
def convert_array_into_image(array: np.array) -> Image:
x = array / array.max()
return Image.fromarray((x * 255).astype(np.uint8))
def blend_windowed_video(video_file: str) -> np.array:
print(f"Decoding... {video_file}")
frames = video_to_array_frames(video_file)
if video_file.startswith("red"):
return red_blend_arrays(reversed(frames))
else:
return blend_arrays(frames, window=files_by_window_size[video_file])
def save_image(image: Image) -> None:
image.save("blend.png", format="png")
print("Saved blend.png file.")
def main():
r = blend_windowed_video("red.mov")
g = blend_windowed_video("green.mov")
b = blend_windowed_video("blue.mov")
blended_array = np.zeros((512, 512, 3))
blended_array[:, :, 0] = r[:, :, 0]
blended_array[:, :, 1] = g[:, :, 1]
blended_array[:, :, 2] = b[:, :, 2]
image = convert_array_into_image(blended_array)
save_image(image)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment