Create JPEGs Automatically With SVG
By Benoit Marchal
2003-12-22
Reader Rating:

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
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).
First published by IBM developerWorks
If you found this article interesting, you may want to read these as well:
» Better SOAP Interfaces With Header Elements
» Variable Substitution In XML Documents
» Grab Headlines From A Remote RSS File
» Tip: Convert from HTML to XML with HTML Tidy
|