MSL HOWTO
Magick Scripting Language Howto
This HOWTO explains how to write MSL scripts which are Image Magick
scripts writen in a XML format.
php-conjure -v, --version
Prints the version of the php-conjure currently used.
To begin, here is a simple MSL script example which opens an image,
blur it and write the result:
<?xml version='1.0' ?>
<msl>
<read filename='image.jpg' />
<blur />
<write filename='image-blured.jpg' />
</msl>
php-conjure -r, --registered-commands
Prints the available commands in this implementation of MSL
php-conjure with their parameters set to their current default values.
For php-conjure version "0.01 g" this gives:
<blur radius='0' sigma='4' />
<charcoal radius='5' sigma='3' />
<contrast sharpen='0' level='2' />
<crop x='10' y='10' width='100' height='100' />
<edge radius='2' />
<emboss radius='5' sigma='3' />
<gaussianblur radius='0' sigma='4' />
<negate />
<enhance />
<equalize />
<normalize />
<flip />
<flop />
<minify />
<magnify />
<oilpaint radius='3' />
<medianfilter radius='2' />
<modulate brightness='100' saturation='100' hue='100' />
<motionblur radius='0' sigma='4' angle='20' />
<reducenoise radius='1' />
<resize width='400' height='400' filter='unknown' />
<scale width='400' height='400' geometry='!' />
<roll x='0' y='0' />
<rotate degrees='60' />
<shade gray='8' azimuth='60' elevation='30' />
<sharpen radius='10' sigma='5' />
<shear x='0' y='0' />
<solarize threshold='10' />
<swirl degrees='30' />
<threshold threshold='2000' />
<wave amplitude='3' waveLength='12' />
<annotation color='#ff0000'
fontface='Palatino-Bold' fontsize='16' style='italic'
x='10' y='60'
annotation='Ahhhh, Cozumel!' />
The values given are the default values that are used if you call one
of those tags without any attributes.
For exemple for this one:
<modulate brightness='100' saturation='100' hue='100' />
You can call it safly like this:
<modulate saturation='142' />
The other parameters won't interfere with the current given one.
The --registered-commands command is also useful as a quickstart for
editing a script using copy-past from it.
php-conjure -g, --generate-code
Generate PHP code equivalent to the script.
With conjure implementations, you can use vars in your MSL scripts.
For exemple, a variable named 'VAR' will have this look %[VAR] in the
MSL script, used as an attribute for a command. Those vars can be set
from the command line when the script is called by the interpreter,
for exemple:
<blur radius='0' sigma='%[blur-level]' />
So you can then set this value while the invokation:
php-conjure incantation.msl --blur-level 4
Set Variables in the MSL script:
<set var='VAR' value='12' />
<print output='\\tVAR => %[VAR]!\\n' />
Modify Variables:
<?xml version='1.0' ?>
<msl>
<set var='VAR' value='18' />
<print output='\\tVAR => %[VAR]!\\n' />
<set var='VAR' op='+' value='2' />
<print output='\\tVAR + 2 => %[VAR]!\\n' />
<set var='VAR' op='/' value='4' />
<print output='\\tVAR / 4 => %[VAR]!\\n' />
<set var='VAR' op='*' value='3' />
<print output='\\tVAR * 3 => %[VAR]!\\n' />
<set var='VAR' op='%' value='4' />
<print output='\\tVAR % 4 => %[VAR]!\\n' />
<set var='VAR' op='+' value='1 3 5 2' />
<print output='\\tVAR + 1 3 5 2 => %[VAR]!\\n' />
<set var='VAR' op='.' value=' here we are' />
<print output='\\tVAR . here we are => %[VAR]!\\n' />
</msl>
When invoked, this MSL incantation will print:
VAR => 18!
VAR + 2 => 20!
VAR / 4 => 5!
VAR * 3 => 15!
VAR % 4 => 3!
VAR + 1 3 5 2 => 14!
VAR . here we are => 14 here we are!
Pointers:
Take care to just use the name of the variable in the var attribute,
without %[ ] , this enables advance features such as pointers usage.
If you do put a var with %[*], a var whose name is the value of the
pointer, will be used.
You can also put vars from command line anywhere else than only in
attributes, for exemple:
<%[blurtype] radius='0' sigma='4' />
So you can then switch on this :
php-conjure incantation.msl -blurtype blur
php-conjure incantation.msl -blurtype gaussianblur
php-conjure incantation.msl -blurtype motionblur
!!! You can not do this with MSL vars set from the script.
!!! Vars set in the script can only be used as attributes.
Overloading Defaults Values:
You set defaults values for your MSL scripts:
<set var='blur-level' value='3' />
<blur radius='0' sigma='%[blur-level]' />
And then overload those values from the invokation:
php-conjure incantation.msl --blur-level 5
(This behavior is due to the command line arguments are apllied by a
"preprocessor" before the XML parsing.)
Get values from an image:
<?xml version='1.0' ?>
<msl>
<read filename='image.png' />
<get
width='WID'
height='HEI'
mimetype='MIME'
imagedepth='DEPTH'
numbercolors='NBCOL'
/>
<print output='\\tThe width is %[WID].\\n' />
<print output='\\tThe height is %[HEI].\\n' />
<print output='\\tThe mime type is %[MIME].\\n' />
<print output='\\tThe depth is %[DEPTH].\\n' />
<print output='\\tThe colors number is %[NBCOL].\\n' />
</msl>
Just call this MSL script with -img anyimage.png to print its width,
height, mime-type, image-depth and the number of colors.
Includes:
<include filename='shadow-incantation-3.inc.msl' />
The file 'shadow-incantation-3.inc.msl' will be included at the place
of this tag. Useful for common macros and routines.
php-cojure is a multi-layer image composition tool.
This means you can compose an image from several images used as
layers.
<group type='merge'>
<layer name='Halo' composite='lighten'>
<read filename='source.png' />
<negate />
<blur radius='8' sigma='6' />
</layer>
<layer name='Halo' composite='none'>
<read filename='source.png' />
</layer>
</group>
<write filename='composed.png' />
Moreover it is a recursive multi-layer image composition tool!
This means the layers with which you can compose an image can itselves
be composed from other layers.
And the maximum depth composition is not limited, the only limit is
your computer capabilities.
TODO: put an exemple
Composite operators available in php-conjure are:
over, in, out, atop, xor, plus, minus, add, subtract, difference,
multiply, bumpmap, copy, copyred, copygreen, copyblue, copyopacity,
clear, dissolve, displace, modulate, threshold, none, darken, lighten,
hue, saturate, colorize, luminize, screen, overlay.
You can also use a number for each one from 1 to 31. Those numbers are
those defined in imagick. You can use the numbers to test more easily
all the possible composite operators to merge two layers.
Here is the equivalent:
1 - over
2 - in
3 - out
4 - atop
5 - xor
6 - plus
7 - minus
8 - add
9 - subtract
10 - difference-
11 - multiply
12 - bumpmap
13 - copy
14 - copyred
15 - copygreen
16 - copyblue
17 - copyopacity
18 - clear
19 - dissolve
20 - displace
21 - modulate
22 - threshold
23 - none
24 - darken
25 - lighten
26 - hue
27 - saturate
28 - colorize
29 - luminize
30 - screen
31 - overlay
<?xml version='1.0' ?>
<msl>
<group type='merge'>
<layer name='Panel' composite='lighten'>
<matrixgradient rows='3' cols='4'
matrix='#AE3421 #C24A2E #BE4636 #A2C24E
#B45239 #A37E10 #B85728 #E1A370
#2EC144 #BE4636 #BE4636 #63BE46' />
<scale width='220' height='160' />
<blur radius='8' sigma='6' />
</layer>
</group>
<write filename='grada1.png' />
<display filename='grada1.png' viewer='display' />
</msl>
The Anthony Thyssen's technique to produce gradients.
But with this tag you can produce real pixelized backgrounds too.
Display results from the script:
<write filename='output-result.png' />
<display filename='output-result.png' viewer='display' />
The "viewer" attribute is the viewer you want to use to see the result
while executing the MSL script. You can put any viewer you want like
kuickshow, gqview, kview or even The Gimp if you wish :)
But if you give no viewer name in the viewer attribute, php-conjure
will takes display of course :)
Loops on lists of words:
<?xml version='1.0' ?>
<msl>
<for value='VAR' in='list January February Mars April'>
<print output='\\tVAR => %[VAR]!\\n' />
</for>
</msl>
Will print:
VAR => January!
VAR => February!
VAR => Mars!
VAR => April!
Loops on sequence of numbers:
<?xml version='1.0' ?>
<msl>
<for value='VAR' in='seq 4 8'>
<print output='\\tVAR => %[VAR]!\\n' />
</for>
</msl>
From 4 to 8 (4 5 6 7 8).
-----------------------------
<?xml version='1.0' ?>
<msl>
<for value='VAR' in='seq 6'>
<print output='\\tVAR => %[VAR]!\\n' />
</for>
</msl>
From 1 to 6 (1 2 3 4 5 6).
-----------------------------
<?xml version='1.0' ?>
<msl>
<for value='VAR' in='seq 8 4 32'>
<print output='\\tVAR => %[VAR]!\\n' />
</for>
</msl>
From 4 to 32, every 4 numbers.
(8 12 16 20 24 28 32)
Alternative syntaxes for list loops on words:
<for value='VAR' in='each January February Mars April'>
<for value='VAR' each='January February Mars April'>
<for value='VAR' list='January February Mars April'>
Alternative syntaxes for list loops on numbers:
<for value='VAR' seq='4 8'>
<for value='VAR' range='4 8'>
<for value='VAR' in='range 4 8'>
(Usefull if you are more used to Python or Bash Syntaxes.)
Keep the last value from a loop:
<?xml version='1.0' ?>
<msl>
<for value='VAR' in='list January February Mars April'>
<print output='\\tVAR => %[VAR]!\\n' />
<!-- %[VAR] is only defined localy inside the loop -->
<set var='LAST' value='%[VAR]' />
</for>
<!-- But it is possible to export its last value -->
<print output='\\tLAST => %[LAST]!\\n' />
</msl>
Switch structures:
<switch value='%[select]'>
<case value='A'>
<modulate hue='3' />
</case>
<case value='B'>
<negate />
</case>
</switch>
Here if you put -select A on the command line, the content of the case
tag with the value A will be selected and the other will be ignored.
If you put -select B, it will apply the negate.
It is possible to import part of a SVG document by their "id" (the
xml id). Those id can be define in Sodipodi in its XML editor.
Here is an example:
<?xml version='1.0' ?>
<msl>
<!-- Default Dimentions: -->
<set var='WIDTH' value='1152' />
<set var='HEIGHT' value='864' />
<!-- Dimentions Switcher: -->
<switch value='%[dim]'>
<case value='1151'>
<set var='WIDTH' value='1152' />
<set var='HEIGHT' value='864' />
</case>
<case value='1024'>
<set var='WIDTH' value='1024' />
<set var='HEIGHT' value='768' />
</case>
<case value='800'>
<set var='WIDTH' value='800' />
<set var='HEIGHT' value='600' />
</case>
<case value='600'>
<set var='WIDTH' value='600' />
<set var='HEIGHT' value='450' />
</case>
<case value='400'>
<set var='WIDTH' value='400' />
<set var='HEIGHT' value='300' />
</case>
</switch>
<merge>
<layer name='The Text elements' composite='multiply'>
<merge>
<layer name='The URL' composite='multiply'>
<svgSelect filename='sodipodi_A02.vec.svg' element='url' type='fill' />
</layer>
<layer name='The small title' composite='multiply'>
<svgSelect filename='sodipodi_A02.vec.svg' element='small-title' type='fill' />
</layer>
<layer name='The Authors' composite='multiply'>
<svgSelect filename='sodipodi_A02.vec.svg' element='text' type='fill' />
</layer>
<layer name='The Bubble' composite='multiply'>
<svgSelect filename='sodipodi_A02.vec.svg' element='bubble' type='fill' />
</layer>
</merge>
<scale width='%[WIDTH]' height='%[HEIGHT]' />
<write filename='/mnt/ramdisk/sodi.png' />
<display filename='/mnt/ramdisk/sodi.png' viewer='display' />
</layer>
<!--
<layer name='The Cute Little Squirel' composite='lighten'>
<svgSelect filename='sodipodi_A02.vec.svg' element='logo' type='fill' />
<blur radius='8' sigma='6' />
<emboss radius='6' sigma='15' />
<negate />
<emboss radius='6' sigma='15' />
<negate />
<emboss radius='6' sigma='15' />
<blur radius='6' sigma='4' />
<scale width='%[WIDTH]' height='%[HEIGHT]' />
<write filename='/mnt/ramdisk/sodi.png' />
<display filename='/mnt/ramdisk/sodi.png' viewer='display' />
</layer>
<layer name='Background' composite='none'>
<matrixgradient cols='4' rows='3'
matrix='#EC0C0D #F23313 #FB891D #FCAB1F
#F64819 #FB8420 #FBA621 #FCB620
#F54218 #FA7D21 #F99E24 #F9AC25' />
<scale width='80' height='60' />
<blur radius='24' sigma='16' />
<scale width='%[WIDTH]' height='%[HEIGHT]' />
</layer>
-->
</merge>
<write filename='/mnt/ramdisk/sodi.png' />
<display filename='/mnt/ramdisk/sodi.png' viewer='display' />
</msl>
Copyright (C) 2003 2004 2005 Florent Monnier aka Blue Prawn.
You can use this documentation either under the Attribution-ShareAlike
licence: http://creativecommons.org/licenses/by-sa/2.5/
or under the Free Documentation Licence:
http://www.fsf.org/licensing/licenses/fdl.html
|