Vector Graphic File Formats
Vector graphics are not represented by a fixed matrix of pixels, but by a collection of points and instructions for connecting those points. Whereas raster graphics cannot be scaled without losing or resampling the image data, vector graphics may be rendered at any scale without a loss of quality.
When we talk about vector graphics, we are actually referring to vector graphic file formats. Vector-based display devices (such as oscilloscopes or the old Vectrex video game console) are rare these days. All of the images that we cover in this book become rasterized in the end, whether it is by the display software, video card, or printer.
The two vector image formats that are of interest to us here are the open standard SVG format (Scalable Vector Graphics) and Macromedia’s SWF format (Shockwave/Flash). You might argue that PostScript and PDF are also vector formats, since each typically defines lines and curves as a series of points and control points. However, nothing in the PostScript language description restricts it to using only vector graphics. You could, for example, craft a well-formed PostScript document in which each page is represented as a raster graphic. PostScript and PDF are more properly defined as high-level document formats, as we shall see later in the chapter.
At first glance, you might think of SVG (described in Chapter 6) and SWF (described in Chapter 8) as competing graphics formats. The two are very different beasts, actually. The overriding design goals of the SWF format have always been efficiency and widespread availability. Today, the best reasons for using SWF are that it is fast and prevalent. Tomorrow, you may find yourself using SVG for many tasks because SVG was designed as the standard way of incorporating vector graphics into XHTML documents. Let’s take a closer look at how you would go about generating SVG and SWF files from Perl.
SVG for XML Images
SVG’s biggest strength is that it is based on XML and can be tightly integrated into XHTML web pages. A graphic representation of a typical XHTML document is shown in Figure 1-6. Let’s say that you want to implement a rollover button in this document, where the text or the outline of the button changes in response to mouse click or mouseover events. Usually this is handled by creating static PNG or GIF images, one for each state of the button. These images are then swapped using JavaScript to handle the mouse events. The problem with using static raster images for each button is that they quickly become difficult to maintain. If the site needs a redesign or if the button text changes, you have to change each of the static files. With an SVG solution, the appearance and the text of the button can be directly changed by the rollover script.[3]
An SVG element is a collection of XML tags that describe the lines, curves, text, colors, and shading of the image. An SVG image can even encapsulate raster image data. Chapter 6 and Chapter 7 describe the tags that make up the SVG specification in depth, but a simple SVG element (four colored squares rotated at a 45 degree angle) looks like this:
<svg width="2in" height="2in" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(144,0) rotate(45) scale(.70)"> <desc>A blue square</desc> <rect width="1in" height="1in" fill="#0000FF"/> <desc>A red square</desc> <rect x="0in" y="1in" width="1in" height="1in" fill="#FF0000"/> <desc>A yellow square</desc> <rect x="1in" y="0in" width="1in" height="1in" fill="#FFFF00"/> <desc>A green square</desc> <rect x="1in" y="1in" width="1in" height="1in" fill="#00FF00"/> </g> </svg>
Because it is plain text, SVG can be generated from Perl using simple print statements. The following produces an equivalent SVG document on STDOUT:
#!/usr/bin/perl -w use strict; my @colors = qw(blue red yellow green); print qq(<svg width="2in" height="2in" xmlns="http://www.w3.org/2000/svg">); print qq(<g transform="translate(100,0) rotate(45) scale(.70)">); foreach my $i (0..3) { print "<desc>A $colors[$i] square</desc>"; print '<rect x="'.int($i/2).'in" y="'.($i%2).'in"'."\n"; print qq(width="1in" height="1in" fill="$colors[$i]"/>); } print "</g></svg>";
One of the fringe benefits of using an XML-based format like SVG is that you can draw upon the library of existing XML parsing and writing tools. Some of the more popular XML Perl modules are:
- XML::Writer and XML::Parser
Writing and reading interfaces to the Expat XML parser.
- XML::Simple
A simplified interface to XML::Parser.
- XML::Twig
An extension of XML::Parser that returns the XML document as a tree structure.
- XML::SAX
A framework for building event-driven SAX (Simple API for XML) parsers, filters, and writers. Other modules, such as XML::SAX::Writer, build on this framework.
- AxKit
A suite of mod_perl-based tools for integrating XML generation with the Apache web server.
- XML::LibXML
An interface to the Gnome libxml2 library.
If you’ve installed the Image::Magick library (see Chapter 3) with XML support, you can easily rasterize SVG files and convert them to other formats. If you run the following code on the previous SVG image, you will notice that it is cropped because ImageMagick does not yet recognize the scaling attribute:
#!/usr/bin/perl -w use strict; use Image::Magick; my $image = new Image::Magick; my $status = $image->Read('image.svg'); die "$status\n" if $status; $image->Write('png:image.png'); undef $image;
Many vector graphics drawing programs such as Adobe’s Illustrator and the free Sketch program (http://sketch.sourceforge.net) support SVG as an interchange format. It is also becoming more accepted on the web, but it is still not as prevalent as the SWF format.
SWF for Flash Animation
The SWF format is Macromedia’s contribution to the Web. Unlike SVG, SWF files are stored in a proprietary binary format. An SWF file is a sequence of opcodes that describe single or multi-frame animations called movies. Movies can be embedded within other movies as sprites, and all elements of the document are scriptable with the ActionScript language. SWF’s strength lies in the size of its installed user base, its efficient use of bandwidth, and its powerful scripting language. SWF is the most powerful and common animation format currently on the Web.
Most people generate SWF files using Macromedia’s Flash tool; in fact, many Flash developers don’t even know that they’re generating SWF files. But there’s no reason you can’t make SWF files from Perl or any other scripting language. In fact, the Ming module provides a high-level API for doing so from Perl, PHP, C, and Java.
The Ming API is most useful as a supplement to the Flash tool, for automating certain tasks, or for creating dynamic SWF movies on the fly. One of the sample Ming applications in Chapter 9 is a program that assembles previously created Flash movies into a new composite movie according to an XML description:
<movie filename="index.swf" width="400" height="400"> <sprite url="sprite2.swf"> <scaleTo x="2" y="8"/> <moveTo x="100" y="100"/> </sprite> <sprite url="sprite2.swf"> <scaleTo x="5" y="5"/> <moveTo x="200" y="200"/> </sprite> <sprite url="sprite2.swf"> <moveTo x="300" y="300"/> <rotateTo degrees="45"/> </sprite> <nextFrame/> </movie>
See Chapter 9 for the full example.
[3] Unfortunately, this is more promise than practice as of this writing; most web browsers still only support SVG with external plug-ins.
Get Perl Graphics Programming now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.