Recently, I had need to add some Eclipse branding graphics to an RCP application.
Rather than take the "easy" route of using an image editor, I thought I'd explore the use of SVG to produce the required images in a declarative kind of way.
Using SVG for this purpose has a number of advantages ...
- they are cross platform
- the declarative, text file nature allows the content to be generated
- they can be created using open-source tools
The downside is that the bitmaps required for Eclipse branding must be in BMP format - not the newer PNG alternative. This is covered in detail in this Eclipse bug report -
https://bugs.eclipse.org/bugs/show_bug.cgi?id=21315.
Fortunately, this can be overcome by converting the SVG images to a bitmap format by using a conversion program called a "rasterizer".
A good example of a rasterizer is Batik - an open-source toolkit for manipulating SVG images.
See http://xmlgraphics.apache.org/batik/tools/rasterizer.html for further details on the Batik rasterizer.
Round Trip exampleHere's a simple example of some SVG source to get started.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="500"
height="330"
id="drawing">
<defs>
<g id="mytext">
<text
xml:space="preserve"
style="font-size:40px;font-weight:normal;text-align:start;line-height:100%;text-anchor:start;font-family:Bitstream Vera Sans"
x="200" y="125">Hello</text>
<text
xml:space="preserve"
style="font-size:40px;font-weight:normal;text-align:start;line-height:100%;text-anchor:start;font-family:Bitstream Vera Sans"
x="200" y="170">World ...</text>
</g>
</defs>
<rect style="fill:black" width="500" height="330" x="0" y="0" />
<use xlink:href="#mytext" style="fill:white" />
</svg>
This produces a result like this:
In order to produce this image for the web, I used the Batik rasterizer. For example, the command I used was this:
C:\>java -jar c:\jshare\batik-1.7\batik-rasterizer.jar drawing5.svg
About to transcode 1 SVG file(s)
Converting drawing5.svg to drawing5.png ... ... success
Once you have a PNG format image, it's a "simple" matter of converting that to a BMP format. The simplicity involved depends on your platform:
- if you're on Windows - you can use Microsoft Paint: open the PNG and then save as BMP
- if you're on Linux - you can use GIMP
Refining your ImageWell, that's produced a very simple image. But one of the advantages of SVG is that you can get very nice effects with a minimum of effort.
Step 1 - Background Gradient
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="500"
height="330"
id="drawing">
<defs>
<g id="mytext">
<text
xml:space="preserve"
style="font-size:40px;font-weight:normal;text-align:start;line-height:100%;text-anchor:start;font-family:Bitstream Vera Sans"
x="200" y="125">Hello</text>
<text
xml:space="preserve"
style="font-size:40px;font-weight:normal;text-align:start;line-height:100%;text-anchor:start;font-family:Bitstream Vera Sans"
x="200" y="170">World ...</text>
</g>
<linearGradient id="top">
<stop offset="0%" style="stop-color: black;"/>
<stop offset="100%" style="stop-color: #484848;"/>
</linearGradient>
</defs>
<rect style="fill:url(#top)" width="500" height="330" x="0" y="0" />
<use xlink:href="#mytext" style="fill:white" />
</svg>
This produces a result like this:
Nice enough, but the default direction for a gradient is from left to right.
Step 2 - Background Gradient - in the correct direction
Here, we use another gradient - with a direction specifier - and embed the first.
<linearGradient id="top">
<stop offset="0%" style="stop-color: black;"/>
<stop offset="100%" style="stop-color: #484848;"/>
</linearGradient>
<linearGradient id="topa"
xlink:href="#top"
x1="0%" y1="0%" x2="0%" y2="100%"/>
</defs>
<rect style="fill:url(#topa)" width="500" height="330" x="0" y="0" />
This produces a result like this:
Step 3 - Background Gradient - with a horizon effectThis refinement adds a horizon - by splitting the image in two - at 200 px down, and using two gradients.
<linearGradient id="top">
<stop offset="0%" style="stop-color: black;"/>
<stop offset="100%" style="stop-color: #484848;"/>
</linearGradient>
<linearGradient id="topa"
xlink:href="#top"
x1="0%" y1="0%" x2="0%" y2="100%"/>
<linearGradient id="bottom">
<stop offset="0%" style="stop-color: #707070;"/>
<stop offset="100%" style="stop-color: black;"/>
</linearGradient>
<linearGradient id="bottoma"
xlink:href="#bottom"
x1="0%" y1="0%" x2="0%" y2="100%"/>
</defs>
<rect style="fill:url(#topa)" width="500" height="200" x="0" y="0" />
<rect style="fill:url(#bottoma)" width="500" height="130" x="0" y="200" />
This produces a result like this:
Step 4 - With a GraphicNaturally, if we are doing a nice, modern style image, we should use some modern styled clip-art to give the image a lift. Since we are using SVG, there is a whole world of choice at the
Open Clip Art project. For my Hello World example, I've chosen a nice clean globe.
In order to use a graphic, download the source to separate file. It can then be included in two different ways:
- cut and paste the source code into your SVG file
- save it to a separate file, and reference it as below using the image tag.
Note that I have applied a scale transformation to make the image fit in.
<g id="globe">
<image xlink:href="globe.svg"
width="500" height="500" x="0" y="0"
transform="scale(0.25)"/>
</g>
</defs>
<rect style="fill:url(#topa)" width="500" height="200" x="0" y="0" />
<rect style="fill:url(#bottoma)" width="500" height="130" x="0" y="200" />
<use xlink:href="#mytext" style="fill:white" />
<use xlink:href="#globe" x="60" y="80" />
This produces a result like this:
Step 5 - With a Reflection
No self-respecting modern image would be complete without the "reflection" technique! This is amazingly simple using SVG - just apply a transform effect on the use tag.
<use xlink:href="#mytext" style="fill:white" />
<use xlink:href="#mytext" style="fill:white;opacity:0.25" transform="matrix(1 0 0 -1 0 400)"/>
<use xlink:href="#globe" x="60" y="80" />
<use xlink:href="#globe" style="opacity:0.25" x="60" y="80" transform="matrix(1 0 0 -1 0 400)"/>
This produces a result like this: