Beruflich Dokumente
Kultur Dokumente
Anime Studio
Document File Format
Anime Studio Document File Format
● Introduction
● Document Overview
○ Zip Container
○ JSON Project Document (Project.animeproj)
● Document Structure
○ Document Header
○ Styles
○ Layer Comps
○ Camera Movements and Timeline Markers
○ Layer Definitions
○ Document View State (optional preference)
● How to find what you are looking for from the old format within the new format?
● How to edit the new format using a text editor
● How to edit the new document format with a scripting tool
● Tools for Beautifying JSON
● Recommended JSON editors
● Python Scripts
1
Introduction
With Anime Studio 11.0, the product team released a brand new document file format. The
older .anme format was replaced with a new JSONbased format (file extension: .anime).
Using a standard format like JSON made it easier to maintain a format that is both
backward and forward compatible as newer versions of Anime Studio are released. It can do
that because the JSON format can organize data in a specific yet flexible hierarchy. This
hierarchy can allow us to add, and in some cases delete data values without breaking the file
format.
In order for the document to save space on user's storage devices, the document format is
also compressed in a container using the Zip file format. Since JSON is a text based format,
Zip dramatically reduces its size on disk.
One of the reasons we picked both JSON and Zip is they are both popular and widely used.
That makes it easier for users to be able to use third party libraries and scripting languages
to manage and manipulate the document if they feel inclined. For example, the scripting
language Python has both JSON parsing and Zip compression decompression builtin.
Using a small bit of scripting, it is quite easy to open, query, modify, and save an existing
document. We'll show an example of this later in the document.
One note about the pre11.0 document format. Anime Studio will continue to read the old
format for the foreseeable future. We realize there is a lot of content out there. While the old
format is considered deprecated, the application should continue to read and convert
documents as old as Anime Studio 6.
2
Document Overview
If you were to try to open up a .anime file in a text editor or hex editor, you most likely
wouldn't understand what you were looking at. This is because the .anime format is using
the Zip compressed file format as a container for the real data of the document.
Zip Container
Zip compression shrinks down the size of the data by looking for duplicated items in the
document and replacing it with binary data that is significantly smaller than the original
information. Since JSON is a text based format, the amount of compression we get is rather
dramatic. We've seen document data reduce in size on disk from 250 MB down to about 4
MB!
If you were to rename your MyAnimeDocument.anime file to MyAnimeDocument.zip , you
could expand the .anime file using any Zip decompression tool (eg StuffIt, WinZip, WinRAR,
etc). One or two files should be created.
■ Project.animeproj the main project file
■ preview.jpg the project thumbnail image
Project.animeproj is the JSON file that defines all the main data about your Anime Studio
document including layers and styles. The whole next section will be about describing this
file.
preview.jpg is the optional thumbnail that is created of the project canvas when the
document was saved. This file is used by the thumbnail previewer on Windows and the
QuickLook plugin on Mac. The reason the thumbnail is optionally in the archive is the image
file will not be created if thumbnail creation is disabled in the Documents preferences. (See
"Document thumbnail preview size")
JSON Project Document (Project.animeproj)
In order to understand how the Anime Studio project document works, it is necessary to
review some of the basics of JSON. Below is an example of the first lines of the project
document. This document has been beautified to add whitespace and color.
3
JSON is a keyvalue based hierarchical file format. This means that you associate data
values from the document by using a specific key. If you want to reference a particular bit of
information in the document, you just have to search for its key. (In the screenshot above,
the keys are in blue.) If you would like to find in the document what date the document was
created, you'd just search the JSON for the "created_date" key. The data value would be the
time stamp. Keyvalue pairs together are considered "properties" of the format.
JSON Key/Value
"created_date": "Fri Jan 22 17:59:49 2016"
The hierarchical part of JSON means that you can associate one or more pieces of
document data by making it be a "parent" or "child" of that data. For example, Anime Studio
4
uses layers to define objects on the canvas (eg Vector, Image, Switch, etc). A vector layer
may be described by many properties such as points, lines, curves. Those drawing types are
in turn are described by even deeper properties such as their location on the canvas and
how they can be animated. The JSON file format keeps track of all those properties by
establishing a parent/child relationship between them. For example, this is a
pseudohierarchical representation for a line in a vector layer:
All Layers > Vector Layer > Line > Line Properties
With JSON, you can also group related data into objects and lists. Objects use { } syntax and
lists use [ ] syntax. An object groups properties together that are related into a unified
concept. For example, if you wanted to define a background color based on it's RGBA
values, you may want to define it this way:
Background Color Object
"back_color": {
"r": 234,
"g": 234,
"b": 234,
"a": 255
},
From the definition it becomes clear which properties are considered red, green, blue, or
alpha by looking at its keys.
A list describes properties, objects, or even other lists that are usually the same type. The
advantage of lists is that they are not fixed sizes. So you can define as many items as you
need. Here is how you may want to define a list of layer comps:
Layer Comps Defined in a List
"layercomps": ["Background","Character 1", "Character 2", ... ]
(Note that the example above isn't exactly how layer comps are defined in the .anime file
format. Properties were removed for brevity.)
Objects and lists are what make JSON a really powerful part of the format because to add
new data, you just have to add a new property or object. Parsers that read and understand
JSON typically ignore information they don't understand. So let's say we add in Anime
Studio 15.0 a new property with a key of "my_new_animation_feature". When Anime Studio
11.0 opens that file, it just ignores that feature. This is good news if the new feature was not
an integral feature of the document. If it is an important feature, you will have to use Anime
Studio 15.0 to make use of it.
5
Document Structure
Now that we have JSON basics under control, let's start going through some of the guts of
the format. Within the JSON document there are a number of different sections:
■ Document Header
■ Camera Movements and Timeline Markers
■ Styles
■ Layer Comps
■ Layer Definitions
■ Document View State
Each section mostly correlates to the old .anme format. The big difference is that in the old
format not all items used a key to define its value. On the surface, that means that the new
JSON file format is a bit bigger and a bit more verbose than the old format. The positive is it
typically makes it much more easier to find the data values you are looking for.
For those who wish to understand more about each of the document sections, they will be
described in more detail below.
Document Header
The document header contains general or projectwide information about the document. It
lives at the very top of the document. In the example below you can see that the header
includes version information, a creation date, as well as a comment the application writes.
There are three versions specified in the header:
● major_version
● version
● rev_version
Anime Studio can use each of these version numbers in different ways. "major_version" is
the major document version. We hope this never happens, but if we have to change the file
format so radically so that old versions of our software can't read it, this number will
increase. "version" is the document version. It is used mostly to let the application know that
this document is newer or older than what the current application can open. If the version
number is newer, a warning will be given to the user that the document has been created
with a newer version of the document. Finally, rev_version is just a revision number. This
revision number is used mostly for internal purposes.
The "project_data" object contains properties that are specific to this project. Most of these
properties come directly from the Project Settings dialog (File>Project Settings) in the
application.
● width/height The project width and height in pixels (eg 720p or 480p) of the export
● start_frame/end_frame The starting and ending frame of the animation
● fps frames per second of the animation
● back_color background color of the canvas
● depth_of_field/focus_distance/focus_range/focus_blur depth of field properties
Document Header
6
"mime_type": "application/xvnd.lm_mohodoc",
"version": 1021,
"major_version": 1,
"rev_version": 0,
"comment": "Created in Moho version 12.0, Copyright © 19992016 Smith Micro Software,
Inc.",
"created_date": "Fri Jan 22 17:59:49 2016",
"project_data": {
"width": 852,
"height": 480,
"start_frame": 1,
"end_frame": 48,
"fps": 24,
"back_color": {
"r": 234,
"g": 234,
"b": 234,
"a": 255
},
"noise_grain": 0,
"pixelation": 0,
"antialiasing": true,
"depth_sort": false,
"distance_sort": false,
"depth_of_field": false,
"focus_distance": 2,
"focus_range": 1,
"focus_blur": 0.050625,
"global_render_style_fill_style": 0,
"global_render_style_line_style": 0,
"global_render_style_layer_style": 0,
"global_render_style_minimize_randomness": true,
"stereo_mode": 0,
"stereo_separation": 1,
"extra_swf_frame": false,
"color_palette": "Basic Colors.png",
"soundtrack": ""
}
Styles
All the global styles of the document are defined in this section.
For each style there is a:
● name
● unique identifier
● line and fill color
● brush name
● brush properties
7
Styles
"styles": [
{
"type": "Style",
"name": "Dragon_Tongue_Shading",
"uuid": "0ff99f9b299b44979f736c38dda5e952",
"define_fill_color": true,
"fill_color": { ... }
"define_line_width": true,
"line_width": 0.001389,
"define_line_col": true,
"line_color": { ... }
"line_caps": 1,
"brush_name": "Brush504.png",
"brush_align": false,
"brush_jitter": 6.283185,
"brush_spacing": 0,
"brush_angle_drift": 0,
"brush_randomize": false,
"brush_merged_alpha": false,
"brush_tint": true
},
{
"type": "Style",
"name": "Dragon_Wing_Dark",
...
}
}
Layer Comps
Layer comps are used to focus on certain layers when composing or rendering. You can
manage the creation, deletion, or updating of layer comps in the Layers palette.
Layer comps in the document are defined by three items:
■ Name
■ Unique identifier (UUID)
■ A list of layer IDs
8
Layer Comps
"layercomps": [
{
"name": "Background",
"uuid": "B85FA8AD2CB143C489E53B86138CAC40",
"layer_ids": [
"DE907C68CD6C4353A5C74D416E208BA7"
]
},
{
"name": "Character 1",
"uuid": "ABC86A51B35443E99D2C5064D8DAD0B0",
"layer_ids": [
"11A8AB8BF7A64E7B987CF08F546E95EF",
"75BAC57EC083470FB81209CF8F2AE032",
"DE907C68CD6C4353A5C74D416E208BA7"
]
},
...
],
The "layer_ids" key specifies a list of layer IDs that are UUIDs. In the layers section of the
document, each layer has a unique layer ID.
Camera Movements and Timeline Markers
Camera movements and timeline markers are defined in the "animated_values" object.
Camera Movements and Timeline Markers
"animated_values": {
"camera_track": { ... },
"camera_zoom": { ... },
"camera_roll": { ... },
"camera_pan_tilt": { ... },
"timeline_markers": { ... }
},
Layer Definitions
The layers section of the document is undoubtably the largest section of any .anime
document. Quite simply, it defines all of the layers and their attributes. Here are the current
layer types:
■ Vector Layer (aka Mesh Layer)
■ Image Layer (includes image and movie types)
■ Audio Layer
9
■ Group Layer
■ Switch Layer
■ Bone Layer
■ Particle Layer
■ Note Layer
■ Text Layer
■ Patch Layer
■ Poser Layer (aka Mesh 3D Layer)
Each of the layers in the Project.animeproj JSON file will have numerous properties
associated with it. In fact it is too many to name in this document. There are some common
properties like type, name, and unique ID, but then there will also be a number of layer
specific properties. For example, an image layer requires that there be a path to the image
file (eg MyPhoto.png)
Layers
"layers": [
{
"type": "ImageLayer",
"name": "Background",
...
},
{
"type": "MeshLayer",
"name": "Character 1",
...
},
...
}
Document View State (optional preference)
In Anime Studio 11, there is a new checkbox in the Documents Preferences to save the
document view state within the document. Enabling "Save and restore view settings in the
document" will add a new "documentviewstate" object. Documents that don't save the view
state, will just use the default values when they are opened.
An example view state property that can be saved with the document happens when you
select View>Show Rule of Thirds in the main menu. Each time you open that document, the
canvas will show the Rule of Thirds grid.
10
Document View State
"documentviewstate": {
"DocState_viewportSetting": 1,
"DocState_gridOn": false,
"DocState_gridStyle": 0,
"DocState_gridSize": 20,
"DocState_gridSnappingOn": true,
"DocState_showOutputOnly": false,
"DocState_showVideoSafeZones": false,
"DocState_showRuleOfThirds": true,
"DocState_viewPortLeftWidthPct": 1,
"DocState_viewPortTopWidthPct": 1,
"DocState_zoom0": 0.9,
"DocState_viewOffset0": { ... },
"DocState_rotation0": 0,
"DocState_stereo0": false,
"DocState_enableOutsideView0": false,
"DocState_outsideViewPitch0": 0,
"DocState_outsideViewYaw0": 0,
"DocState_outsideViewRadius0": 0,
"DocState_outsideViewAttn0": { ... },
...
"DocState_playStart": 1,
"DocState_playEnd": 1
}
How to find what you are looking for from the old format within the new
format?
The old .anme document format that was used in Anime Studio 10 and earlier was a custom
format. While the format was text based, there were some format issues that made it difficult
to add new properties without breaking the format. Since you just had to drag and drop a
.anme file into a text editor, it was relatively trivial to make changes if you knew some basics
about the format. The good news is that the new document format tries to mimic the sections
of the old format. There was a Document Header, Layer Comp, Style, and Layer section to
the document. If you have an older .anme file, opened it Anime Studio 11, converted the
document to .anime and than compared the documents sidebyside, a lot would match up.
The main big difference is every property now must have a key associated with values. That
means that it should be easier to find a certain value in the document if you know it's key. So
if you want to change a value of an Image Layer, all you'd need to do is search for
"ImageLayer" in the JSON file. Find the specific image layer if there is more than one. Then
you just find the property that you want to change. For example, if you wanted to enable the
Toon Effect on that image layer, you'd continue your search and look for the key
"toon_effect".
11
12
example, a vector layer may be made up 100s of shapes. Those shapes may have 100s of
points. Editing one of these points may be extremely difficult using just the document file.
How to edit the new format using a text editor
1. Copy the Anime Studio document from MyAnimeDocument.anime to a new file
named MyAnimeDocument.zip .
2. Expand the .zip file using a decompression tool like StuffIt, WinZip, WinRAR, or the
Zip mechanism built into your machine.
3. There should be two files that are expanded: Project.animeproj and preview.jpg
4. Beautify the Project.animeproj file. (See below)
5. Open the Project.animeproj file in a text editor.
6. Make your edits to the text file
7. Zip the Project.animeproj using a compression tool like above. Make sure to choose
the .zip format, not 7z or RAR.
8. Name the archive MyModfiedAnimeDocument.zip
9. Once zipped, rename the document to MyModifiedAnimeDocument.anime .
10. Try and open in Anime Studio.
In step 4 you will most likely need to "beautify" or "pretty" up the Project.animeproj file
before it is edited in the Text Editor. In order to save space on the user's computer, the
Project.animeproj file had all unnecessary whitespace characters (spaces, tabs, new lines)
removed by Anime Studio when saved. Beautifying means that you are adding all that back
in just so that it will be easy to edit. There are a number of tools that will do this for you. In
the section below, there will be links to beautifiers. The sample code provided below also
show how to beautify programmatically.
There is no need to remove all of the whitespace/newline characters after making your edits
in step 6. The next time that the document is saved, the whitespace will again be removed.
In step 7, it is not necessary to Zip the preview.jpg file. This is purely optional. The thumbnail
preview will be regenerated the next time the document is saved.
Also in step 7, keep in mind that some Zip tools use their own Zip format for compression
(eg WinZip). Make sure you specify in the application preferences the most "portable"
version of the .zip format. That is usually LZ compression.
How to edit the new document format with a scripting tool
Editing the new document format with a scripting tool follows the same general path as
manually editing from the section previous. The difference is you can automate the Zip
compression/decompression as well as the browsing/editing of the JSON. At the bottom of
this document there are two Python scripts that you can use as an example. Other scripting
languages have support for Zip and JSON, either through builtin support or by using a
library.
13
Scripting Pseudo Code
// Unzip the .anime file
...
// Open the Project.animeproj file
...
// Use the JSON parser to look for 1 or more keys
...
// Print/Edit the values for the key(s)
...
// Close the Project.animeproj file
...
// Zip the Project.animeproj back to the original .anime file
...
Tools for Beautifying JSON
With AnimeStudio removing all of the whitespace and newline characters from the
document, it will be necessary to beautify to text to make it easier to search for keys and
values. Here are a list of tools we use within Smith Micro to help beautify.
JQ JSON Query Utility Commandline tool for Mac or Windows
BBEdit or TextWrangler JSON Text Filter Beautifier (Mac only)
JS Beautifier
(Web)
JSON Beautifier & Formatter (Web)
JSON Beautifier (Web)
Recommended JSON editors
JSON editors can help you visualize a JSON file by syntax coloring and collapsing lists and
objects.
JSON Editor Online (Web)
Notepad++ with
JSTool
plugin (Windows)
Xcode (Mac)
BBEdit
orTextWrangler (Mac)
Keep in mind that JSON is just text. So it can be opened with your favorite text editor. It
might not have syntax coloring, but it can get the job done.
14
Python Scripts
Below are two Python 2.x scripts. The first one just extracts 1 or more .anime files to JSON.
MyAnimeDocument.anime become MyAnimeDocument.json.
Extract to JSON
1 #!/usr/bin/env python
2 """Extract To JSON Takes 1 or more .anime file and converts it to JSON
3 extract_to_json.py <.anime files>
4 """
5 import os
6 import os.path
7 import json
8 import shut
9 import sys
10 import zipfile
11
12 def ExtractToJSON(animepath, beautify = False):
13 (
if not os.path.exists(animepath)):
14
print 'ERROR: %s does not exist' % animepath
15
return
16
17
# Get the folder and the file name for the path
18 folder, animefilename = os.path.split(animepath)
19
print 'Extracting from ' + animefilename + '...'
20
21
# Open the .anime file
22 with zipfile.ZipFile(animepath) as zip_file:
23
# Iterate over all of the items in the zip file
24
for item in
zip_file.namelist():
25 filename = os.path.basename(item)
26
27
# skip everything except the .animeproj file, which is JSON
28
if filename ! = 'Project.animeproj' :
29 continue
30
# Create the extracted .json path name
31 filename, ext = os.path.splitext(animefilename)
32 filename += '.json'
33 jsonpath = os.path.join(folder, filename)
34
# Load the JSON from the zip file and dump it beautified to the .json path
35 source = zip_file. open
(item)
36
if
(beautify):
37 json_obj = json.load(source)
38 json.dump(json_obj, file
(jsonpath, "wb" ), sort_keys=False)
39
else :
40 shutil.copyfileobj(source, file
(jsonpath, "wb"))
41
15
16
This second script allows you to list, extract or update an existing .anime without even
opening the file.
Anime Util Manipulate a .anime file
1 #!/usr/bin/env python
2 """anime_util Manipulate a .anime file
3 Commands are list, extract, and update.
4 list prints the paths of image and audio layers.
5 extract saves the Project.animeproj to a desired location.
6 update replaces existing paths with the one supplied.
7 anime_util.py h |command| for help.
8 """
9 import zipfile
10 import json
11 import argparse
12 import os
13 import sys
14
15 def extractProject(animeFile):
16 """Return the Project.animeproj extracted from a zip file as a string."""
17 zf = zipfile.ZipFile(animeFile)
18 for filename in
[
'Project.animeproj' ]:
19 data = zf.read(filename)
20
21 return data
22
23 def writeProject(animeFile, projectData):
24 """Write data back into Project.animeproj in a zip file"""
25 zf = zipfile.ZipFile(animeFile, mode= "w"
)
26 zf.writestr( 'Project.animeproj' , projectData)
27
28 def printLayerInfo(layer):
29 """Print the path of an image or audio layer."""
30 if
layer.has_key( 'image_path' ):
31 print "image:" , layer['image_path' ]
32
33 if
layer.has_key( 'audio_path' ):
34 print "audio:" , layer['audio_path' ]
35
36 def updateLayerInfo(layer, update):
37 """Replace the path of an image or audio layer."""
38 if
layer.has_key( 'image_path' ):
39 path = layer[ 'image_path' ]
40 layer[ 'image_path' ] = path.replace(update[ 0 1
], update[ ])
41
42 if
layer.has_key( 'audio_path' ):
43 path = layer[ 'audio_path' ]
44 layer[ 'audio_path' ] = path.replace(update[ 0 1
], update[ ])
17
45
46 def isContainerLayer(layer):
47
"""Return True if the layer is a group or switch layer."""
48
type = layer[ 'type']
49
return
type == "GroupLayer" or
type == "SwitchLayer"
50
51 def iterateContainerLayer(groupLayer, update=None):
52 """Iterate a group or switch layer descending into sub groups and updating or
printing layers otherwise."""
53
for layer in groupLayer:
54
if
isContainerLayer(layer):
55 iterateContainerLayer(layer[ 'layers'], update)
56
else :
57
if
update:
58 updateLayerInfo(layer, update)
59
else :
60 printLayerInfo(layer)
61
62
63 def iterateLayers(path, update=None):
64
"""Iterate the root project layers."""
65 projectPath = path
66 projectData = extractProject(projectPath)
67
68
if
len (projectData) > 0:
69 jsonData = json.loads(projectData)
70 layers = jsonData[ 'layers'
]
71 iterateContainerLayer(layers, update)
72
if
update:
73 writeProject(projectPath, json.dumps(jsonData))
74 iterateContainerLayer(layers)
75
76 def extractProjectFile(animeFile, projectFilepath = None):
77
"""Iterate Project.animeproj to projectFilePath."""
78 jsonData = extractProject(animeFile)
79
80
iflen (jsonData) > 0:
81 jsonData = json.loads(jsonData)
82
if
projectFilepath:
83 output = file
(projectFilepath, 'wb')
84
else :
85 output = (
file'Project.animeproj' ,
'wb')
86
87 json.dump(jsonData, output, sort_keys=False, indent= 4
)
88
else :
89 parser.error( "Project.animeproj is empty" )
90
91
92
93 def perform():
18
19