Overview
Graffiti Markup Language (.gml) is a universal, XML-based, open file format designed to store graffiti motion data (x coordinates, y coordinates and time). The format is designed to maximize readability and ease of implementation for even hobbyist programmers, artists and graffiti writers. Popular applications currently implementing GML include Graffiti Analysis and EyeWriter. Beyond storing data, a main goal of GML is to spark interest surrounding the importance (and fun) of open data and introduce open source collaborations to new communities. GML is intended to be a simple bridge between ink and code, promoting collaborations between graffiti writers and hackers. GML is today’s new digital standard for tomorrow’s vandals.
Credits:
Originally created by: Evan Roth, Chris Sugrue, Theo Watson and Jamie Wilkinson
- GML concept by: Evan Roth and Theo Watson
- Project lead: Evan Roth
- Technical lead: Jamie Wilkinson
- The GML v1.0 Spec Doc was created by: Golan Levin, Evan Roth, Jérôme Saint-Clair, Chris Sugrue, Jamie Wilkinson and Theo Watson (most of which are card carrying members of F.A.T. – Free Art & Technology).
- Supported by:
- Constant, Association for Art and Media, Brussels http://www.constantvzw.org
- Free Art & Technology http://fffff.at
History
The idea of recording graffiti motion data and saving it in a text file as a series of X,Y and time coordinates started back in 2003 with Evan Roth’s original version of Graffiti Analysis. Graffiti Analysis (the current version of which can be viewed here) is open source software designed for digitally archiving and displaying graffiti motion data. The idea of defining, standardizing and opening this data type came in the summer of 2009 in conversations between Evan Roth, Theo Watson, Chris Sugrue and Jamie Wilkinson. The first two projects released using the GML standard were Graffiti Analysis 2.0 and the initial version of the EyeWriter. The Free Art & Technology Lab (FAT Lab) hosted the first GML Week in January 2010. Since then dozens of third party applications have been developed by open source hackers and almost 20,000 gml tags have been uploaded to #000000book (the open .gml database).
GML is one node in the open graffiti triangle: open source software (Graffiti Analysis), open data (#000000book) and open data formats (Graffiti Markup Language).
Related initiatives
- InkML: Ink Markup Language http://www.w3.org/TR/InkML/
- SVG: Scaleable Vector Graphics http://www.w3.org/Graphics/SVG/
GML Specs
The Graffiti Markup Languages specifications are public domain.
<gml spec='1.0'>
<tag>
<header>
<client> <!-- how, who, what and where -->
<name>Laser Tag</name> <!-- application name -->
<version>2.0</version> <!-- application version -->
<username>MyUserName</username> <!-- user name on 000000book.com, optional -->
<permalink>http://000000book.com/data/156/</permalink> <!-- URL to .gml data on 000000book.com, optional -->
<keywords>katsu,paris,2010</keywords> <!-- comma-separated -->
<uniqueKey>28sks922ks992</uniqueKey> <!-- iPhone uuid, MAC address, etc -->
<ip>192.168.1.1</ip>
<time>1928372722</time> <!-- unixtime -->
<location>
<lon>-39.392922</lon>
<lat>53.29292</lat>
</location>
</client>
<!-- This is all stuff that relates to the orientation and dimensions of the client -->
<!-- So that we know how to re-map the 0.0-1.0 coordinates that come in for each point -->
<!-- Also for figuring out the down vector for devices with accelerometers and how that effects drips -->
<!-- All numbers should be between 0.0 - 1.0 -->
<environment>
<offset>
<x>0.0</x>
<y>0.0</y>
<z>0.0</z>
</offset>
<rotation>
<x>0.0</x>
<y>0.0</y>
<z>0.0</z>
</rotation>
<up>
<x>0.0</x> <!-- commonly up for iphone apps -->
<y>-1.0</y> <!-- most common -->
<z>0.0</z>
</up>
<screenBounds> <!-- use this as your multipler to get 0.0 to 1.0 back to right size - pts should never go off 0.0 to 1.0 -->
<x>1024</x>
<y>768</y>
<z>0</z>
</screenBounds>
<origin>
<x>0</x>
<y>0</y>
<z>0</z>
</origin>
<realScale> <!-- how these units relate to real world units - good for laser tag -->
<x>1000</x>
<y>600</y>
<z>0</z>
<unit>cm</unit>
</realScale>
<audio>youraudio.mp3</audio> <!-- path to audio file -->
<background>yourimage.jpg</background> <!-- path to image file -->
</environment>
</header>
<drawing>
<!-- for all stroke and movement stuff it helps to have everything inside the stroke tag -->
<!-- this way it is easy to get a sense of order to events -->
<stroke isDrawing='false'> <!-- for non drawing mouse movements -->
<pt>
<x>0.0</x>
<y>0.0</y>
<z>0.0</z> <!--this is optional -->
<t>0.013</t> <!-- time is optional too -->
<!-- NOTE: older versions of GML use <time> instead of <t> -->
</pt>
</stroke>
<stroke> <!-- by default stroke drawing is true -->
<!-- each stroke could be drawn with a different brush -->
<!-- if no brush tag is found for a stroke then it inherits the previous settings -->
<brush>
<mode>0</mode> <!-- same as uniqueStyleID but an internal reference -->
<uniqueStyleID>LaserTagArrowLetters</uniqueStyleID> <!-- unique blackbook string for your style -->
<!-- see note about spec at the bottom - like unique style but with extra info -->
<spec>http://aurltodescribethebrushspec.com/someSpec.xml</spec>
<width>10</width>
<speedToWidthRatio>1.5</speedToWidthRatio> <!-- put 0 for fixed width -->
<dripAmnt>1.0</dripAmnt>
<dripSpeed>1.0</dripSpeed>
<layerAbsolute>0</layerAbsolute> <!--Think photoshop layers-->
<color>
<r>255</r>
<g>255</g>
<b>255</b>
<a>255</a> <!-- optional -->
</color>
<dripVecRelativeToUp> <!-- what angle do our drips go in relation to our up vector -->
<x>0</x>
<y>1</y>
<z>0</z>
</dripVecRelativeToUp>
</brush>
<pt>
<x>0.0</x>
<y>0.0</y>
<z>0.0</z> <!--this is optional -->
<t>0.013</t> <!-- time is optional too -->
</pt>
<pt>
<x>0.0</x>
<y>0.0</y>
<z>0.0</z> <!--this is optional -->
<t>0.023</t> <!-- time is optional too -->
</pt>
</stroke>
<!-- this stroke inherits the previous stroke properties -->
<!-- but changes color and draws on the layer below -->
<stroke>
<info> <!-- optional info - more stuff soon-->
<curved>true</curved>
</info>
<brush>
<color>
<r>255</r>
<g>255</g>
<b>0</b>
</color>
<layerRelative> <!-- this means one layer bellow the previous layer -->
-1
</layerRelative>
</brush>
<pt>
<x>0.0</x>
<y>0.0</y>
</pt>
<pt>
<x>0.0</x>
<y>0.0</y>
</pt>
</stroke>
<stroke>
<pt>
<pres>0.5</pres> <!-- Optional. Preasure range from 0 to 1 -->
<rot>0.5</rot> <!-- Optional. Rotation range from 0 to 1 for 0 to 2*PI -->
<dir> <!-- Optional Direction -->
<x></x> <!-- range from 0 to 1 -->
<y></y> <!-- range from 0 to 1 -->
<z></z> <!-- Optional inside direction. Range from 0 to 1 -->
</dir>
</pt>
</stroke>
</drawing>
</tag>
</gml>