Skip to content

Instantly share code, notes, and snippets.

@Everlag
Last active January 20, 2020 13:32
Show Gist options
  • Save Everlag/8344fa7c9234900ba2cb851581c62599 to your computer and use it in GitHub Desktop.
Save Everlag/8344fa7c9234900ba2cb851581c62599 to your computer and use it in GitHub Desktop.
Loop through all in srcframes and run primitive over it, details in script.
# Loop through all in srcframes and run primitive over it
# Primitive: https://github.com/fogleman/primitive
#
# Dependencies: primitive, ffmpeg, and inkscape in path
#
# This supports job resumption with 'resume' and will keep track
# of frames which have been done.
#
# To clear for another set of srcframes, remove contents of
# vecframes and rastframes
# Image extraction for populating srcframes with
# ./ffmpeg -i Berserk22.mkv -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr srcframes/frame%0d.png
#
# This gets us i-frames which are great for sampling interesting portions
# of the video.
#
# Alternatively, dump every frame of a 24fps.
# Running this through primitive will take a month.
# ./ffmpeg -i Berserk22.mkv -r 24/1 srcframes/frame_%0d.png
# MIT licensed
# Allow resumption but default to not overriding existing jobs
#
# Resumption typically involves deleting the completed srcframes
resume="$1"
if [[ $resume != "resume" ]]; then
if [ "$(ls -A rastframes)" ]; then
echo "rastframes not empty, use 'resume' to ignore"
exit 1
fi
if [ "$(ls -A vecframes)" ]; then
echo "vecframes not empty, use 'resume' to ignore"
exit 1
fi
fi
# Keep track of files we've completed
log="rastframes/completed.txt"
touch $log
# Primitive settings
primitiveN=6000
for file in srcframes/*.png; do
# Grab base and annotate N
base=$(basename $file)$primitiveN
vector="vecframes/${base%.*}.svg"
raster="rastframes/${base%.*}.png"
# Check to ensure file is not already completed
if grep -Fxq "$base" $log; then
echo "$base done, skipping"
continue
fi
# Extract dimensions of form 'width x height' using file and grep
# Something something regex something two problems :)
dimensions=$(file --brief $file | grep -Eo [0-9]*[[:space:]]x[[:space:]][0-9]*)
# Isolate dimensions and use xargs to trim whitespace
# This is dangerous for anything but single strings w/o whitespace :|
width=$(echo $dimensions | grep -Eo [0-9]*[[:space:]] | xargs echo -n)
height=$(echo $dimensions | grep -Eo [[:space:]][0-9]* | xargs echo -n)
echo "primitive $base"
# Vectorize with primitive
GOMAXPROCS=1 primitive -i $file -o $vector -n $primitiveN
echo "inkscape $base rendering $width x $height"
# Convert vector to raster
./inkscape/inkscape -z $vector --export-png=$raster \
--export-width=$width --export-height=$height
# Mark this file as completed
echo $base >> $log
done
@jamen
Copy link

jamen commented Sep 30, 2016

Very cool script. Nicely done. It was close to something else I was thinking of.

I'm wonder if someone could make a script that takes a video, takes each frame, and does the static animation in the main repo to each one, then reconstructs the video into a new sketch-like animation.

@chrisgloom
Copy link

I'm really appreciating how well commented this is!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment