Framerator
As I have mentioned, building my Numberline iOS app has involved lots and lots of animation frames. I have been doing my artwork in Inkscape and then generating the frames based on the content in layers. It has been ok generating the low res frames I have been using for testing as I went along, but when I realised I needed to go back to all my SVG files and re-generate all the animation frames in three resolutions (iPad, iPhone and Retina) it became obvious that I could no longer do this by hand in Inkscape (show appropriate frames, file export, type the correct frame file name, set the resolution, export ... ugh).
I'm a programmer right? So it makes sense to automate that stuff. I wrote this simple Python script to run through a whole pile of SVGs, generate temporary SVG files containing a set of pre-configured layers and then drive Inkscape on the command line to generate the animation frame.
Here is the code:
from svgfig import *
import os
import config
inkscape_location = '/Applications/Inkscape.app'
def generateFile (detail):
# load it and save it using SVG fig. This will write out elements on single lines.
svg = load(detail[0])
svg.save ("temp.svg")
# now we can mess with temp.svg using regex hackery
fileOut = open ("temp_out.svg", "wt")
fileIn = open ("temp.svg", "rt")
lines = fileIn.readlines ()
for line in lines:
# is this line a layer?
exp = "(.*style=\\\")([^\\\"]+)(\\\".*inkscape:label=\\\")([^\\\"]+)(\\\".*inkscape:groupmode=\\\"layer\\\".*)"
regexp = re.compile(exp, re.I)
match = regexp.search(line)
if (match):
layer = match.group(4)
if (layer in detail[4]):
# this is a layer we want
fileOut.write(match.group(1) + "display:inline" + match.group(3) + match.group(4) + match.group(5))
else:
# hide this layer
fileOut.write (match.group(1) + "display:none" + match.group(3) + match.group(4) + match.group(5))
else:
# otherwise just write out the line
fileOut.write (line)
fileIn.close ()
fileOut.close ()
# run our command to generate the PNG based on our temporary SVG
command = inkscape_location + '/Contents/Resources/script -without-gui -export-area-page --export-width=' \
+str(detail[2])+' -export-height='+str(detail[3])+' --export-png='+os.getcwd()+'/'+detail[1] + ' ' + os.getcwd() + '/temp_out.svg'
print (command)
os.system(command)
for detail in config.config:
generateFile (detail)
It depends on svgfig to sanitise the input and the following config file to describe the SVG files and the frames you need to generate:
# an array of tuples describing your SVG and the required output
# [0] - The SVG file in question
# [1] - The required PNG file to generate
# [2] - The width
# [3] - The height
# [4] - An array of layer numbers to show in the generated PNG
config = [
#left wobble
("monster_wobble_left.svg", "wobble_left4.PNG", 147, 201, ["Wobble3","Wobble3-bg"]),
("monster_wobble_left.svg", "[email protected]", 295, 402, ["Wobble3","Wobble3-bg"]),
("monster_wobble_left.svg", "ipad_wobble_left4.PNG", 323, 440, ["Wobble3","Wobble3-bg"]),
("monster_wobble_left.svg", "wobble_left3.PNG", 147, 201, ["Wobble2","Wobble2-bg"]),
("monster_wobble_left.svg", "[email protected]", 295, 402, ["Wobble2","Wobble2-bg"]),
("monster_wobble_left.svg", "ipad_wobble_left3.PNG", 323, 440, ["Wobble2","Wobble2-bg"]),
("monster_wobble_left.svg", "wobble_left2.PNG", 147, 201, ["Wobble1","Wobble1-bg"]),
("monster_wobble_left.svg", "[email protected]", 295, 402, ["Wobble1","Wobble1-bg"]),
("monster_wobble_left.svg", "ipad_wobble_left2.PNG", 323, 440, ["Wobble1","Wobble1-bg"]),
("monster_wobble_left.svg", "wobble_left1.PNG", 147, 201, ["standing","standing_bg"]),
("monster_wobble_left.svg", "[email protected]", 295, 402, ["standing","standing_bg"]),
("monster_wobble_left.svg", "ipad_wobble_left1.PNG", 323, 440, ["standing","standing_bg"]),
#right wobble
("monster_wobble.svg", "wobble4.PNG", 147, 201, ["Wobble3","Wobble3-bg"]),
("monster_wobble.svg", "[email protected]", 295, 402, ["Wobble3","Wobble3-bg"]),
("monster_wobble.svg", "ipad_wobble4.PNG", 323, 440, ["Wobble3","Wobble3-bg"]),
("monster_wobble.svg", "wobble3.PNG", 147, 201, ["Wobble2","Wobble2-bg"]),
("monster_wobble.svg", "[email protected]", 295, 402, ["Wobble2","Wobble2-bg"]),
("monster_wobble.svg", "ipad_wobble3.PNG", 323, 440, ["Wobble2","Wobble2-bg"]),
("monster_wobble.svg", "wobble2.PNG", 147, 201, ["Wobble1","Wobble1-bg"]),
("monster_wobble.svg", "[email protected]", 295, 402, ["Wobble1","Wobble1-bg"]),
("monster_wobble.svg", "ipad_wobble2.PNG", 323, 440, ["Wobble1","Wobble1-bg"]),
("monster_wobble.svg", "wobble1.PNG", 147, 201, ["Standing","standing_bg"]),
("monster_wobble.svg", "[email protected]", 295, 402, ["Standing","standing_bg"]),
("monster_wobble.svg", "ipad_wobble1.PNG", 323, 440, ["Standing","standing_bg"]),
]
You can find the repo on Github
Permalink - Tags: Development