In the world of graphics, two major rendering technologies have dominated the scene. The first and foremost, bitmap rendering, has been around for decades, and technologies and tools revolving around it have greatly matured. Images can be displayed in many formats, namely, jpeg, png, bmp, and so on. Designers, with the help of advanced tools, are capable of generating impressive and sophisticated imagery to be used on Web sites, giving them a fresh look. Tools like Adobe® Photoshop and Image Editor have a long list of advanced algorithms that can be applied to a bitmap of an image and are capable of changing the entire look and feel of it. This has been adopted well, and bitmap images have now become an important part of any Web site design. However, as it stands now, the bitmap rendering suffers from two important drawbacks: First, it is a static image with no motion to it. (Note that we can support animations using the gif format, but most of these animations are predefined and generally do not accommodate user interaction.) Second, they are suited to a particular resolution, or at best a set of resolutions, for which the beauty of an image remains intact. Once the resolution is changed, you start seeing those ugly rectangles (pixel squares), which deteriorate the image quality and take away its luster. Therefore, bitmaps, though capable of generating fantastic images, at best serve a particular domain of interest, where things are static and screen resolutions are fixed.
With the need for growing dynamics in Web content, it is imperative that these images "talk" and "respond" to user interaction. In other words, images need to have a behavioral aspect to them. Scalable Vector Graphics (SVG) do just that. It is important to understand what the words "Scalable Vector Graphics" mean. Vector Graphics means that the images drawn are not a collection of colored pixels. A vector drawing is like a pencil drawing where you take a pencil from one point to another and connect the points with straight lines, curved lines, rectangles, and ellipses. You eventually fill the closed area with various colors. Therefore, a concept of path is fundamental to vector drawings. The benefit is that this path is independent of screen resolution. Generally, the paths are developed on a unit scale, and then the entire graphic is rendered to whatever resolution the user wants, so the image quality remains unchanged even if the resolution is changed to absurd limits. We call vector drawings "scalable" because they can potentially scale to any resolution that is supported by the platform (generally a Web browser).
SVG does come with limitations, though. It is a fairly new technology, and the tools have not matured enough to generate graphics at the same level of detail as a bitmap. Additionally, defining complicated paths for a sophisticated image is not easy. As a result, SVG drawings have mainly been limited to simple circles, rectangles, and the like. Things are improving. New emerging technologies are focused on providing full support for SVG, and tools are getting more advanced.
In this article, I will explain SVG in more detail and show its advantages in comparison to bitmaps. Then I will focus on the current tools and technologies that provide support for SVG, primarily those that are open source. Next, I'll explain how you can use the best of both worlds to create sophisticated, yet "living", graphics using bitmap and SVG together. Finally, I'll provide one such example and walk you through the source code.
An introduction to SVG features
Lately, SVG has picked up momentum. Web site designers have started considering SVG as a robust alternative to bitmaps. Almost all the new RIA (Rich Internet Application)-enabled technologies provide support for vector graphics in some form or the other, and SVG does have some advantages as compared to bitmaps. To start with, SVG is a text-based representation. The entire description of an SVG image is represented by an XML format which has been standardized by W3C. This makes SVG images "human readable" and easily changed with a text editor. Any path in an SVG file can be located by parsing the XML or using advanced techniques like XQuery or XPath. This makes SVG capable enough to respond to user needs.
As an example, suppose that you are making an SVG image of a tiger and you want the tiger's eyes to blink when the user clicks a button. In bitmaps, this would normally be done by embedding two or three images which will overlap with each other to produce the effect. However, in SVG, you can locate the path that draws the shape of the eye of the tiger and then refill this path with a different color, thereby making the appearance that the tiger has closed its eyes! Better still, in an SVG editor, you can draw both the areas (an area is a closed path), the open eye and the closed eye, keeping the latter transparent. To make the tiger blink, you alternate the transparency between the two areas by locating both the areas and paths in the corresponding XML. The end result is an interactive SVG image that changes its behavior based on user interaction.
Many more such interactions are possible by manipulating the paths. In fact, SVG allows you to embed sciplets (ECMAScript), which can include events like mouse-over, mouse-out, click, and so on. The features of SVG make it a serious candidate in graphics technologies, providing two advantages as compared to bitmaps:
- You get a scalable image that is independent of screen resolution.
- The corresponding size of an SVG image is smaller as compared to that of the bitmap images which are required to achieve the same effect.
The SVG images, being represented as pure text, can be compressed using some of the well-known text compression algorithms like gzip. Such compressed formats are represented as .svgz files, as opposed to .svg files for uncompressed ones.
Open source tools and technologies supporting SVG
Many open source tools and technologies provide excellent support for SVG image designing. Inkscape (see Resources) is one such tool that is worth mentioning. It is free to use and is an excellent platform to create impressive art work. Inkscape allows users to save images not only in SVG format, but in many other formats as well, like XAML (Microsoft® XAML), PS (post script), GPL (GIMP Palette), ODG (OpenDocument Drawing), and so on. You can also export images as bitmap files. Inkscape provides a feature-rich editor to draw sophisticated images with gradients, Beziers, 3D fillers, and so on. It is definitely worth a look for SVG enthusiasts.
Nearly all the latest technologies support vector drawing today, such
as Microsoft's Silverlight, Sun®'s JavaFX, OpenLazlo, and Adobe Flex (or
Flash). In this article, I will focus more on the support provided by Flex.
Flex, an enterprise-oriented variant of Adobe's Flash Player, is a powerful
platform for RIA-enabled Web sites. Since Flex inherits most of its features
from Flash, it has very good support for vector drawing. Every class in Flex
that extends from the base class Sprite, has an
embedded graphics object in it. This graphics object can be used to do vector
drawing on the sprite. For example, see the code to draw a circle of radius 5:
Listing 1. Example showing the basics of vector drawing
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300"
creationComplete="onCC()">
<mx:Script>
<![CDATA[
private function onCC() : void {
graphics.clear();
graphics.lineStyle(2,0xffff00);
graphics.drawCircle(100,100,5);
}
]]>
</mx:Script>
</mx:Canvas>
|
In
this case, we have extended from the Canvas (which eventually extends from
Sprite), and once the creationComplete event is
fired by Canvas, we draw our circle. Note the graphics.clear() call. It is important to clear the previous
graphic before a new graphic is drawn. Otherwise, the new drawing will be
rendered on top of the older drawing, which will eventually slow down the
process because of redrawing over the top of each other. graphics.lineStyle() sets the style of line which is to be used for
drawing. Finally, graphics.drawCircle() draws a
circle with center (100,100) and radius 5. It is really that simple. Flex
supports the union or intersection of shapes as well. Let's say you have two
circles, and you want to fill only the non-intersecting sections of these
circles. Listing 2 shows how you can do
that.
Listing 2. Example showing intersection or union of two vector drawings
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300"
creationComplete="onCC()">
<mx:Script>
<![CDATA[ private function onCC() : void {
graphics.clear();
graphics.lineStyle(1,0,0);
graphics.beginFill(0xcccccc);
graphics.drawCircle(100,100,50);
graphics.drawCircle(110,100,50);
graphics.endFill();
}
]]>
</mx:Script>
</mx:Canvas>
|
Figure 1 shows what the image looks like when rendered in a browser:
Figure 1. Vector image rendered in a browser
Besides these, the graphics class exposes a lot of other convenient methods that can be used to draw other basic shapes like rectangles, curves, rounded rectangles, lines, triangles, and so on. These should meet the basic requirements of an application developer who wants to use them in a Web site design. However, such basic shapes fall short of expectations when it comes to some heavy duty vector drawing. In such a case, you must make use of some other tools or frameworks that provide advanced support. Degrafa (see Resources) is one such excellent open source framework for creating complex images that are fully interactive as well. The upcoming version of Flex, Flex 4.0, is also going to provide framework-level support for sophisticated SVG drawings. The downside of this is that you have to learn these new APIs to make use of them. However, there is one more way, a sort of middle path, which can help you make good use of bitmaps and vector drawing. I'll explain in the next section.
Using bitmaps and SVG together in Flex
Let's say you want to create a gauge component with three zones in it: Normal, Warning, and Threat. The entire range of zones is from 210 degrees to -30 degrees. This range is divided into three parts. The "threat" zone extends from 210 degrees to 130 degrees. The "warning" zone extends from 130 degrees to 50 degrees, and finally the "normal" zone extends from 50 degrees to -30 degrees. The following figure shows the gauge component.
Figure 2. Gauge component
This is a static image with all the gradients and fills. However,
we need to add "life" to it, by adding a needle which shows the current state
of some process based on some event. This needle requires an input from the
user, and based on that, the gauge component places the needle in the
appropriate zone. This kind of interactivity is difficult, if not impossible,
to achieve using bitmaps alone. However, using vector drawing, you can achieve
it. First, code a needle using vector drawing. Then extend from
the base class UIComponent, and override the updateDisplayList() method to draw the custom vector
drawing.
Listing 3. Basic design of a needle component
<?xml version="1.0" encoding="utf-8"?>
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
private var _angle : Number;
// this angle must range from 210 deg to -30 deg:
public function set angle(value : Number) : void {
if(value > 210 || value < -30) throw new Error("Unsupported Angle Value "+value);
_angle = value;
inited = true;
invalidateDisplayList();
}
private var inited : Boolean;
public var center : Point;
public var radius : Number;
public function get angle() : Number {
return _angle;
}
]]>
</mx:Script>
</mx:UIComponent> |
The
needle component declares three variables that it needs before it can display
a needle. Those are "angle", "center", and "radius". You also check for the
valid angle range when setting the value. Finally, you call invalidateDisplayList() to redraw. Now, take a look at the
updateDisplayList() method and see what is
happening
there:
Listing 4. Main drawing code for the needle component
override protected function
updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
// we need to first convert the angle to a convenient value,
since flex follows a different angle convention:
var ang : Number = -angle*Math.PI/180;
graphics.clear();
graphics.beginGradientFill(GradientType.RADIAL,[0,0xcccccc],[1,1],
[20,200],null,SpreadMethod.REFLECT);
graphics.drawCircle(center.x,center.y,30);
graphics.endFill();
if(inited) {
graphics.lineStyle(10,0,1,false,"normal");
graphics.lineGradientStyle(GradientType.LINEAR,[0,0xcccccc],[.5,.5],
[20,200],null,SpreadMethod.REFLECT,"rgb",.5);
graphics.moveTo(center.x,center.y);
var p : Point = getCoordinates(ang);
graphics.lineTo(center.x + p.x,center.y + p.y);
graphics.lineStyle(1,0,0);
graphics.moveTo(center.x,center.y);
} |
For an angle of 30 degrees, the needle component looks like Figure 3.
Figure 3. Needle component at 30 degrees
All that is needed now is to superimpose the bitmap and this vector drawing, and you should have a gauge component ready. See the following code snippet:
Listing 5. Gauge component
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:components="article2.components.*" backgroundColor="0xffffff">
<mx:FormItem label="Change the angle" x="20" y="10">
<mx:HSlider id="slider" minimum="-30" maximum="210" value="0"
liveDragging="true" change="needle.angle = slider.value"/>
</mx:FormItem>
<mx:Canvas y="50" backgroundImage="article2/images/gauge_skin.PNG"
width="362" height="310" id="gauge"/>
<components:Needle id="needle" center="
{new Point(gauge.x+gauge.width/2,gauge.y+gauge.height/2)}" radius="100"/>
</mx:Application> |
Figure 4 shows a snapshot of the above code in action.
Figure 4. Gauge component in action
And that's it; the working gauge component is ready! You can download the working swf file below.
This article gave
a brief description of SVG and bitmaps. You saw how
SVG can help bring user interaction to static bitmaps. Embedding a rich
bitmap is fairly easy in Flex (by providing the backgroundImage property),
and adding a component with vector drawing is even easier. This example opens
up a new door of opportunities where an application designer or developer can
make the best use of both worlds, while sticking to traditional bitmap drawing
and using Flex to add SVG support.
| Description | Name | Size | Download method |
|---|---|---|---|
| .swf file created in this article | Download.zip | 279KB | HTTP |
Information about download methods
Learn
- See the W3C specs for Scalable Vector
Graphics.
- Stay current with developerWorks technical events and webcasts.
Get products and technologies
- Learn about and download Inkscape for a variety of
platforms.
- Get more information about
the Degrafa framework.
-
IBM trial
products for download: Build your next development project with IBM
trial software, available for download directly from developerWorks.
Discuss
-
developerWorks
blogs: Get involved in the developerWorks community.

Sandeep Malik is a Tech Lead for IBM Cognos NOW! and works out of India Software Labs, Pune. He has been involved in the design and architecture phase of new generation UI for the Cognos NOW!, and in memory and real-time streaming OBI (Operation Business Intelligence) engine. Sandeep has extensive experience in heavy duty graphics, charting libraries, client-side streaming, non-blocking I/Os, and in general, asynchronous systems. Prior to IBM, Sandeep worked in a network security domain, analyzing the patterns that change the network traffic distribution (for example, botnets, worm scans, and so on). He has also worked on implementing Servlets 2.4 spec in one of his previous companies. During his free time, he enjoys watching cricket and wishes that in his next life he could become a cricketer, too!





