Creating Scalable Vector Graphics with Perl
Scalable Vector Graphics (SVG) is a compact XML language to
describe two-dimensional images. With SVG you can create extremely
sophisticated images complete with paths, layering, masks, opacity
control, animation, scriptable interactivity, and a small host of
other advanced features -- all using nothing more than your favorite
text editor or XML tools. This month we talk about creating SVG
documents quickly and simply using Perl and David Megginson's
A complete overview of SVG is beyond the scope of this article; if you are new to SVG, and have not done so already, I highly recommend that you have a look at J. David Eisenberg's excellent Introduction to Scalable Vector Graphics before proceeding.
It's worth noting that SVG requires a special browser plug-in or standalone viewer to view the rendered markup as the intended image. Rather than requiring readers to download one of these tools in order to view the results of the code samples, I have rasterized and exported the generated SVG images into Portable Network Graphics (PNG) using a utility that ships with the Apache Software Foundation's Batik project. Do not be confused: the images you will see below are PNGs, but the SVG source for each example is still available with this month's sample code.
A Simple Example -- Just Another Perl (XML) Hacker
|How are you using SVG to add dynamic image generation to your web projects?|
|Post your comments|
For our first example we will write a simple script that creates an SVG banner memorializing our commitment to Perl and XML.
use strict; use XML::Writer; my $image_height = 60; my $image_width = 200; my $writer = XML::Writer->new(); $writer->xmlDecl('UTF-8'); $writer->doctype('svg', '-//W3C//DTD SVG 20001102//EN', 'http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd'); $writer->startTag('svg', height => $image_height, width => $image_width); $writer->emptyTag('rect', height => $image_height, width => $image_width, fill => '#005580'); $writer->startTag('g', id => 'mainGroup', transform => 'translate(24,42)', style => 'font-size:42;font-weight:bold;'); $writer->dataElement('desc', 'JAPH with an XML twist. Features a simple drop shadow.'); $writer->startTag('text', transform => 'translate(3, 3)', style => 'fill:#003955'); $writer->characters('<japh/>'); $writer->endTag('text'); $writer->startTag('text', style => 'fill:#FFFFFF'); $writer->characters('<japh/>'); $writer->endTag('text'); $writer->endTag('g'); $writer->endTag('svg'); $writer->end();
Running this script generates the following XML document:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN" "http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd"> <svg height="60" width="200"> <rect height="60" width="200" fill="#005580" /> <g id="mainGroup" transform="translate(24,42)" style="font-size:42;font-weight:bold;"> <desc>JAPH with an XML twist. Features a simple drop shadow.</desc> <text transform="translate(3, 3)" style="fill:#003955"> <japh/> </text> <text style="fill:#FFFFFF"> <japh/> </text> </g> </svg>
If you view this document in an SVG-enabled browser or standalone SVG viewer, you'll see something like the following.
This amusing little twist on the traditional JAPH block will certainly not win any design awards; but, aesthetics aside, when you compare this method of scripted image creation to those provided by other modules (that often, themselves, depend on cranky and platform-specific libraries) the true power of combining Perl and SVG becomes obvious.
Let's move on to a more serious example.
Pages: 1, 2