Skip to content

Instantly share code, notes, and snippets.

@tdhooper
Last active September 13, 2022 12:03
Show Gist options
  • Save tdhooper/f9e24ded5eec5be8c2a953db9425db8e to your computer and use it in GitHub Desktop.
Save tdhooper/f9e24ded5eec5be8c2a953db9425db8e to your computer and use it in GitHub Desktop.
from wand.image import Image, COMPOSITE_OPERATORS
from wand.drawing import Drawing
from wand.display import display
import sys
import os
import re
import glob
import pprint
start_frame = int(sys.argv[1])
end_frame = int(sys.argv[2])
overlap = int(sys.argv[3])
keyframe_dirs_root = sys.argv[4]
frame_count = end_frame - start_frame
RE_NUMBER = r'(\d+)';
'''
keyframes_and_frames = {
keyframe_index : {
frame_index : frame_path
}
}
'''
keyframes_and_frames = {}
for keyframe_dir in os.scandir(keyframe_dirs_root):
if not keyframe_dir.is_dir():
continue
match = re.search(RE_NUMBER, keyframe_dir.name)
if not match:
continue
keyframe_index = int(match.group(0))
keyframes_and_frames[keyframe_index] = {}
for image_path in glob.glob(os.path.join(keyframe_dir.path, "*.png")):
match = re.search(RE_NUMBER, os.path.basename(image_path))
if not match:
continue
frame_index = int(match.group(0))
keyframes_and_frames[keyframe_index][frame_index] = image_path
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(keyframes_and_frames)
'''
example overlap of 3, start_frame of 3 end_frame of 8
keyframe : frames
_
3: 0 1 2 3 4 5 6
_
5: 2 3 4 5 6 7 8
_
7: 4 5 6 7 8 9 10
'''
def unlerp(min, max, value):
return (value - min) / (max - min)
def smoothstep(edge0, edge1, x):
if x < edge0:
return 0
if x >= edge1:
return 1
x = (x - edge0) / (edge1 - edge0)
return x * x * (3 - 2 * x)
'''
frame_composition = [
[
(path, weight),
...
],
...
]
'''
frame_compositions = []
for frame_index in range(start_frame, end_frame):
keyframes = sorted(keyframes_and_frames.keys())
first_keyframe = next(i for i in reversed(keyframes) if i <= frame_index)
overlapping_keyframe_indicies = [
i for i in range(first_keyframe, frame_index + overlap)
if i in keyframes
]
composition = []
print(frame_index)
for keyframe in overlapping_keyframe_indicies:
if keyframe not in keyframes_and_frames:
continue
images = keyframes_and_frames[keyframe]
if frame_index not in images:
continue
#weight = smoothstep(keyframe - overlap, keyframe, frame_index)
weight = unlerp(keyframe - overlap, keyframe, frame_index)
weight = min(weight, 1.0)
composition.append((images[frame_index], weight))
print(" - {} ({})".format(keyframe, weight))
frame_compositions.append(composition)
#pp = pprint.PrettyPrinter(indent=4)
#pp.pprint(frame_compositions)
for i, composition in enumerate(frame_compositions):
with Image(filename=composition[0][0]) as base_img:
for (path, weight) in composition[1:]:
with Image(filename=path) as img:
base_img.composite(image=img, left=0, top=0, operator='blend', arguments='{}%'.format(weight*100))
base_img.save(filename="output/out_{}.png".format(str(i).zfill(len(str(frame_count)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment