///Create JPEGs Automatically With SVG

Create JPEGs Automatically With SVG

Use Scalable Vector Graphics To Create Images By The Dozen

In this tip, Benoit Marchal discusses a pragmatic approach to Scalable Vector Graphics (SVG). Until the SVG viewer becomes as ubiquitous as the Macromedia Flash player, it will be difficult to incorporate SVG images directly into a Web site. In the meantime, Web developers benefit from generating JPEGs and other bitmaps through SVG. SVG is especially helpful because it is pure XML.

Scalable Vector Graphics (SVG) is an image format developed by the W3C. Since it is based on XML, you can generate images through stylesheets and other XML scripts. This makes SVG a valuable addition to a Web developer and webmaster toolkit. In this tip, I’ll show you how to use SVG to generate images automatically, such as from statistical data.

Just what is SVG?

SVG is an XML vocabulary for describing vector images. The two types of images are: bitmap and vector. A bitmap (JPEG, GIF, or PNG file) is a grid of pixels that represents an image. A vector image (SVG or Macromedia Flash) describes the image in terms of basic shapes such as circle, rectangle, lines, or curves. Adobe Photoshop is an editor for bitmaps, while Adobe Illustrator is an editor for vector images.

Headless Gaphics

Batik requires Graphics2D, the standard Java API for 2D graphics, to generate the images. This may be a problem with UNIX or Linux Web servers because Graphics2D needs an X11 server, which seldom runs on Web servers. Since JDK 1.4, you can run a so-called

Headless Application

by setting the java.awt.headless property to true. Note that the JDK still links to the X11 library, but the server doesn’t need to be started. You can set the property directly on the command line:



java -Djava.awt.headless=true
-jar batik-rasterizer.jar chart.svg

Bitmaps tend to be larger files and are more difficult to resize without losing quality. Imagine an image with a circle 50 pixels in diameter. The corresponding bitmap must be at least 50 x 50 pixels in size, or 2,500 individual pixels. If the circle had a diameter of 100 pixels, the bitmap would be 100 x 100 pixels in size, making it four times as large (10,000 individual pixels). JPEG, GIF, and PNG files are compressed to reduce file size. While compression helps to a certain extent, bitmaps still tend to be larger than vector images.

Indeed, the corresponding vector image has only one instruction: “Draw a circle of 50 pixels.” Furthermore, the larger circle does not require a significantly larger file (it becomes “draw a circle of 100 pixels”). Unfortunately, not every image can be decomposed in basic shapes — for example, it does not work with photos. So bitmaps play a useful role, but for those images that can be decomposed into basic shapes such as diagrams, logos, and chemical formulas, a vector file format is inherently more efficient.

Making a bitmap bigger or smaller results in loss of image quality. Indeed, when you double the dimensions of the pixel grid, you have four times as many pixels so you need to extrapolate almost three quarters of the image! Conversely, to double a vector image, you simply draw larger shapes.

Today, the most popular vector format on the Web is Macromedia Flash — a great format supported by several vendors, but it is also a proprietary tool. SVG is a new standard, developed by the W3C, as an alternative to Flash.

The Web design community has much discussed the wisdom (or lack thereof) of using SVG instead of Flash. The main concern is that while Flash is available to 97 percent of PC users, SVG is not yet as widespread. Things may change and, since SVG is a standard, you should expect that browsers will eventually support it, but it may take years before it is as ubiquitous as Flash.

A Pragmatic Application

Even though it is not as readily available as Flash, using SVG today still has its advantages. One of the attractions of SVG is that it is an XML vocabulary, so it is easy to tweak SVG files with familiar tools such as XML parsers, scripts, and XSL stylesheets. To work around the lack of browser support, it is possible to convert SVG images into formats that are widely supported, such as GIFs or JPEGs.

Apache offers an open-source SVG renderer, Batik (see Resources). Batik comes in different forms and shapes, including a browser to view images, tools to create images, and a rasterizer. I’m most interested in the rasterizer, since it can convert SVG files to bitmaps.

Enough talk — it’s time to code. Listing 1 is a Python script that creates a bar chart from a set of data. Note that you don’t have to use Python for this tip to work — Perl, JavaScript, the Java language, and, most importantly, XSL stylesheets work equally well. The point is that since SVG files are XML, any XML tool is appropriate.

Listing 1. printsvg.py



from sys import stdin

def read_data():
data = []
line = stdin.readline()
while line != '\n' and line != '':
data.append(line.split())
line = stdin.readline()
return data

def print_bars(data):
position = 0
for i in data:
height = int(i[1]) * 2
if height > 200:
height = 200
print ' <rect x="%(x)i" y="%(y)i" width="30" \
height="%(height)i"/>' % { 'x': position * 40 + 10,
'y': 200 - height, 'height': height }
print ' <text x="%(x)i" y="215">%(text)s\
</text>' % { 'text': i[0], 'x' : position * 40 + 20 }
position += 1
return

def print_svg(data):
print u'<?xml version="1.0"?> \
\n<svg xmlns="http://www.w3.org/2000/svg" \
\n id="body" \
\n width="%(width)i" \
\n height="220" \

\n viewBox="0 0 %(width)i 220"> \
\n <polyline style="stroke:black; fill:none" id="axis" \
points="0,0 0,200 %(width)i,200"/> \
\n <g id="boxes" style="stroke:black; fill:green; \
text-anchor: middle">' % { 'width': len(data) * 40 + 10 }
print_bars(data)
print ' </g> \
\n</svg>'
return

if __name__ == "__main__":
print_svg(read_data())

In Listing 1, I kept the bar chart simple. First the script draws the axis, then it loops over the data and draws the bars as rectangles. It also draws labels as text. It would not be difficult to improve on the graphics, like drawing the bars in 3D or using different colors. If you’d like to learn more about writing SVG shapes, check the developerWorks tutorials (see Resources).

The script is a filter, so it expects its input from the standard input and it writes the results on the standard output. It expects the data to be presented in lines where each line holds two pieces of data — the line label and a percentage. Use the redirection operators to work with files, as in:



python printsvg.py < data.txt > chart.svg

Listing 2 is a sample data set. Obviously, you can generate dozens of images in seconds by feeding different data sets to the script. This can be useful in statistical applications.

Listing 2. data.txt



Jan. 43
Feb. 34
Mar. 98
Apr. 29
May 52
Jun. 33
Jul. 15
Aug. 11
Sep. 65
Oct. 78
Nov. 98
Dec. 87

To convert the SVG image to a more common format, install the Batik rasterizer (see Resources) and issue the following command:



java -jar batik-rasterizer.jar chart.svg

Running the script in Listing 1 with the data from Listing 2 will ultimately produce the image in Figure 1:

Figure 1. The bar chart example

The bar chart example

By default, the rasterizer creates PNG files. If you’d rather create JPEGs, use the following command:



java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 chart.svg

The -m specifies the image MIME type and the -q is the quality factor for the JPEG (a number between 0 and 1).

Variations On The Theme

Variations on the theme

The main benefit of using SVG and the Batik toolkit to produce images through XML is that every XML tool, including scripts and stylesheets, is now suitable to produce Web graphics.

I illustrated the technique with a bar chart, but the same technique applies for other images such as navigation buttons, technical drawings, and UML models. Note that you do not have to generate the entire image in your script. To import logos and other graphics created with an image editor, such as Adobe Illustrator, follow these steps:

  • In the image editor, save the image as SVG.
  • In the script, insert the following instruction: <use xlink:href="logo.svg"/>
  • With the Batik rasterizer and the flexibility of XML, you will find no shortage of applications for SVG.

    Resources

    • Download the Batik toolkit used in this article. It includes the rasterizer, which can convert SVG files to bitmaps.

    • Read the developerWorks tutorial “Introduction

    to Scalable Vector Graphics
    ” (February 2002) by Nicholas Chase for additional insight on the pros and cons of the techniques discussed in this article.

    • Move beyond the basics with “Interactive, dynamic Scalable Vector Graphics” (developerWorks, June 2003), which discusses more advanced features of SVG.

    • Try the Adobe SVG Zone, a good place to get started with SVG. It includes links to download the SVG viewer (to enable SVG in your browser), demonstrations, and tutorials.

    • Find more XML resources on the developerWorks XML zone.

    • For a complete list of XML tips to date, check out the tips summary page.

    • IBM’s DB2 database provides not only relational database storage, but also XML-related tools such as the DB2 XML Extender which provides a bridge between XML and relational systems.

    • Visit the DB2 Developer Domain to learn more about DB2. Find out how you can become an IBM Certified Developer in XML and related technologies.

    2010-05-26T17:08:35+00:00 December 22nd, 2003|XML|0 Comments

    About the Author:

    Benoit Marchal is a Belgian consultant. He is the author of XML by Example and other XML books. Benoit is available to help you with XML projects. You can contact him at bmarchal@pineapplesoft.com or through his personal site at marchal.com.

    Leave A Comment