Every now and then, one of my kids will bring home a piece of art that I think is pretty neat. I have often thought about using MS PowerPoint to turn their ideas into vector based clipart but never got around to it.
Recently, my daughter Kristen brought home what I thought was a neat drawing of a Christmas tree. Sure I'm biased, but I thought it was cool. The Christmas tree looked something like this:

So how would I convert this tree into vector format? The most obvious way that came to mind was to load the raster image into MS Powerpoint and then trace vector shapes over it. After the tracing was done, I would delete the raster image and save to a vector format. EMF used to be a popular vector format (1), but now SVG (2a) is more popular. In fact, SVG files can be easily used in modern browsers; unfortunately, there oddly doesn't seem to be a method to save PowerPoint 2010 Files directly to SVG. After Binging around, I found out that most people wanting to save to SVG would first save the PPT File to PDF or EMF and then use a converter to change the PDF or EMF to SVG format as mentioned in (3).
So in this particular case, PowerPoint did not help me much. Also, while there were are a handful of free vector drawing tools out there, most of them seemed to be associated with: Google; the GNU Public License (GPL); or, the Free Software Foundation (FSF) in some way. Because I'm presently attempting to boycott Google and the FSF, I choose to not use tools affiliated with those entities unless absolutely necessary. Of course, if you think my "boycott" is a bit on the silly side, you can be encouraged that learning how to manually create SVG Files may provide you with the following benefits:
- cleaner product output and higher file readabilty
- knowlege of SVG Fundaments that can be used for dynamic content generation
When I looked at my daugher's picture, I noticed that *most* of it could be represented by several closed polygons while the rest of it could be approximated by filled ovals. Given that fact, it become easier to translate my daughter's tree into a vector based format.
I figured that closed polygons could be used to express the rectangle stump, tree body, garland, and star. Then, I figured that the ornaments could be approximated with the mentioned ovals. Fortunately, it was and is easy to represent filled ovals (2d) and closed polygons (2b) in SVG. So I proceeded to determine the minimal necessary SVG document structure.
I found a good starting point for the basic SVG Document Structure at (2f). When I striped out all of what I considered unnecessary except for the demo circle, then I came up with:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Some Copyright Statement Might Go Here -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<desc>Some Circle</desc>
<circle cx="100" cy="100" r="100"
fill="red" stroke="blue" stroke-width="10" />
</svg>
So after I got the basic document structure, I got rid of the circle and began to start tracing out the polygons per (2b). Before I started that, however, I had to make a quick hack to Kristen's picture. I needed to raise Kristen's star up a bit and get it off the tree allowing for some sort of a stand. I did that with the following crude wireframe:

Yes. I know. I should be ashamed for butchering my child's artwork, but this wireframe *may* come in handy when I trace out the vector image.
So using the SVG Polygon Element mentioned previously, I:
- opened up the WireFrame in Paint.Net
- zoomed in and
- hovered the mouse pointer over each of the sections of Kristen's star recording the point coordinates

When I finished, I had code that looked something like this:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!--
©2014 - Shawn and Kristen Grace Eary
Licened via FCML
https://www.utilars.com/Home/FCML
References
[1] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
http://www.w3.org/TR/SVG/shapes.html#PolygonElement.
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<desc>Yellow Star</desc>
<polygon fill="yellow" stroke="black" stroke-width="10"
points="955,60 903,207 757,215 860,288 785,450
936,370 950,360 977,382 1061,437 1035,317 1111,225
1004,225" />
</svg>
The above code then rendered into a star that looked something like this png:

So now that the star was drawn, I needed to draw the base that supported the star using a similar method. The only difference was that this time care was needed to ensure the snap points from Figure#1 were used. If I didn't use the previously mentioned snap points, then there could have been holes in the rendered image when it was rescaled, translated, or rotated. Below is a diagram that shows how I walked through the points:

After drawing the star base, the code looked something like this:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!--
©2014 - Shawn and Kristen Grace Eary
Licened via FCML
https://www.utilars.com/Home/FCML
References
[1] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
http://www.w3.org/TR/SVG/shapes.html#PolygonElement.
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<desc>Yellow Star and Base</desc>
<polygon fill="yellow" stroke="black" stroke-width="10"
points="955,60 903,207 757,215 860,288 785,450
936,370 950,360 977,382 1061,437 1035,317 1111,225
1004,225" />
<polygon fill="brown" stroke="black" stroke-width="10"
points="950,360 936,370 931,476 830,554
880,554 1058,554
1105,554 973,476 977,382" />
</svg>
I then proceeded to draw the rest of the tree using the (880, 554) and (1058,554) snap points from the start base and introducing new snap points as necessary. A figure of this process looked something like this:

I then ended up with code that looked like this:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!--
©2014 - Shawn and Kristen Grace Eary
Licened via FCML
https://www.utilars.com/Home/FCML
References
[1] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
http://www.w3.org/TR/SVG/shapes.html#PolygonElement.
-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
width="4000" height="4000">
<desc>Yellow Star and Base</desc>
<polygon fill="yellow" stroke="black" stroke-width="10"
points="955,60 903,207 757,215 860,288 785,450
936,370 950,360 977,382 1061,437 1035,317 1111,225
1004,225" />
<polygon fill="brown" stroke="black" stroke-width="10"
points="950,360 936,370 931,476 830,554
880,554 1058,554
1105,554 973,476 977,382" />
<polygon fill="green" stroke="black" stroke-width="10"
points="880,554
730, 1023 714, 1076
469, 2005 455, 2103
16, 3468 1, 3521
736, 3521 1184, 3521
2050, 3521
1800, 2634 1760, 2553
1357, 1464 1345, 1361
1058, 554" />
</svg>
Notice above the new definition of width and height attributes
for the SVG tree. Without these, neither IE11 nor FireFox 26.0
seemed to render the whole tree. After the new dimensions were
applied, however, I still needed to zoom to a
size of less than 100% to see the full image. I think I had
to zoom to about 20%.
I found out later that this large
amount of unzoom was necessary because I needed to use a smaller viewport
and scalling.
I then drew the tree trunk using the (736, 3521) (1184, 3521) snap points from the previous example and two new ordinary points (736, 3977) (1184, 3977). At this point, the tree got too big so I had to also apply a scale (2c) transformation to shrink the tree into a size that can be displayed in the the browser. Once the scale was applied, I was able to go back to "100% zoom" which is the default for most browsers. This left the code like the following:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!--
©2014 - Shawn and Kristen Grace Eary
Licened via FCML
https://www.utilars.com/Home/FCML
References
[1] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
http://www.w3.org/TR/SVG/shapes.html#PolygonElement.
[2] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace.
-->
<!-- You can see a basic frame for an SVG File at [1] -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
preserveAspectRatio="xMinYMin meet"
width="4000" height="4000">
<desc>Undecorated Tree</desc>
<!-- You can see an example of scaling at [2] -->
<g transform="scale(0.2)">
<!-- You can see an example of polygon use at [1] -->
<polygon fill="yellow" stroke="black" stroke-width="10"
points="955,60 903,207 757,215 860,288 785,450
936,370 950,360 977,382 1061,437 1035,317 1111,225
1004,225" />
<polygon fill="brown" stroke="black" stroke-width="10"
points="950,360 936,370 931,476 830,554
880,554 1058,554
1105,554 973,476 977,382" />
<polygon fill="green" stroke="black" stroke-width="10"
points="880,554
730, 1023 714, 1076
469, 2005 455, 2103
16, 3468 1, 3521
736, 3521 1184, 3521
2050, 3521
1800, 2634 1760, 2553
1357, 1464 1345, 1361
1058, 554" />
<polygon fill="brown" stroke="black" stroke-width="10"
points="736,3521 736,3977 1184,3977 1184,3521" />
</g>
</svg>
Next I added the garland to the Christmas tree. The snap points for this were already defined in Figure 4, so I used those and inserted the following new polygon:
<polygon fill="silver" stroke="black" stroke-width="10"
points="
16,3468 1,3521
1800,2634 1760,2553
551,2055
1357,1464 1345,1361
730,1023 714,1076
1250,1430
469,2005 455,2103
1670,2630
" />
You can see a trace of the points used in Figure#5

The next step I did was to add the circular like ornaments. I used the SVG Ellipse Shape for that using the technique mentioned in (2d). Like before, I used Paint.NET to hover over locations where I wanted to put Kristen's ornaments and to find a default width. Here is some code to add a few oval ornaments:
<ellipse cx="747" cy="1582" rx="50" ry="50"
fill="blue" stroke="black" stroke-width="10" />
<ellipse cx="1220" cy="1990" rx="50" ry="100"
fill="blue" stroke="black" stroke-width="10" />
By now, however, it became apparent that the colors used were a bit bland, so I started looking into the use of gradients. I wanted to define the gradients for the ornaments at this point because there would be several of them later. I used the information at (2e) for assistance.
Here is some code I used to apply gradients to the ornaments using the HSL model that Mr. LePage blogs about at (4). It seems more convenient to me to apply gradients using HSL than the old RGB method since the lighting percentage can be easily manipulated to obtain different shades of the of the color.
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!--
©2014 - Shawn and Kristen Grace Eary
Licened via FCML
https://www.utilars.com/Home/FCML
References
[1] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
a) http://www.w3.org/TR/SVG/shapes.html#PolygonElement.
b) http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace.
c) http://www.w3.org/TR/SVG/shapes.html#CircleElement
d) http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
-->
<!-- You can see a basic frame for an SVG File at [1a] -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
preserveAspectRatio="xMinYMin meet"
width="4000" height="4000">
<desc>Partially Decorated Tree</desc>
<!-- You can see an example of scaling at [1b] -->
<g transform="scale(0.2)">
<defs>
<!-- You can see examples of how to apply gradients at 1c -->
<radialGradient id="blueCircleGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(226, 100%, 75%)" />
<stop offset="100%" stop-color="hsl(226, 100%, 25%)" />
</radialGradient>
</defs>
<!-- You can see an example of polygon use at [1a] -->
<polygon fill="yellow" stroke="black" stroke-width="10"
points="955,60 903,207 757,215 860,288 785,450
936,370 950,360 977,382 1061,437 1035,317 1111,225
1004,225" />
<polygon fill="brown" stroke="black" stroke-width="10"
points="950,360 936,370 931,476 830,554
880,554 1058,554
1105,554 973,476 977,382" />
<polygon fill="green" stroke="black" stroke-width="10"
points="880,554
730, 1023 714, 1076
469, 2005 455, 2103
16, 3468 1, 3521
736, 3521 1184, 3521
2050, 3521
1800, 2634 1760, 2553
1357, 1464 1345, 1361
1058, 554" />
<polygon fill="brown" stroke="black" stroke-width="10"
points="736,3521 736,3977 1184,3977 1184,3521" />
<polygon fill="silver" stroke="black" stroke-width="10"
points="
16,3468 1,3521
1800,2634 1760,2553
551,2055
1357,1464 1345,1361
730,1023 714,1076
1250,1430
469,2005 455,2103
1670,2630
" />
<!-- You can see examples of how to draw ellipses at 1c and
apply gradients at 1d -->
<ellipse cx="747" cy="1582" rx="50" ry="50"
fill="url(#blueCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="1220" cy="1990" rx="50" ry="100"
fill="url(#blueCircleGradient)" stroke="black"
stroke-width="10" />
</g>
</svg>
After I added the gradients to the ornaments, I decided to go ahead and apply gradients to the rest of the tree. After creating the mentioned gradients, I put on the final ornaments. The final tree (for this blog post) is contained in this SVG Code:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!--
©2014 - Shawn and Kristen Grace Eary
Licened via FCML
https://www.utilars.com/Home/FCML
References
[1] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
a) http://www.w3.org/TR/SVG/shapes.html#PolygonElement.
b) http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace.
c) http://www.w3.org/TR/SVG/shapes.html#CircleElement
d) http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
-->
<!-- You can see a basic frame for an SVG File at [1a] -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
preserveAspectRatio="xMinYMin meet"
width="350" height="600">
<desc>Christmas Tree</desc>
<!-- You can see an example of scaling at [1b] -->
<g transform="scale(0.15)">
<defs>
<!-- You can see examples of how to apply gradients at 1c -->
<radialGradient id="blueCircleGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(226, 100%, 75%)" />
<stop offset="100%" stop-color="hsl(226, 100%, 25%)" />
</radialGradient>
<radialGradient id="redCircleGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(0, 100%, 100%)" />
<stop offset="100%" stop-color="hsl(0, 100%, 50%)" />
</radialGradient>
<radialGradient id="yellowCircleGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(55, 85%, 90%)" />
<stop offset="100%" stop-color="hsl(55, 100%, 40%)" />
</radialGradient>
<radialGradient id="greenTreeGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(122, 68%, 47%)" />
<stop offset="100%" stop-color="hsl(122, 68%, 12%)" />
</radialGradient>
<radialGradient id="garlandGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(196, 32%, 96%)" />
<stop offset="100%" stop-color="hsl(196, 32%, 66%)" />
</radialGradient>
<radialGradient id="brownGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(0, 73%, 50%)" />
<stop offset="100%" stop-color="hsl(0, 73%, 30%)" />
</radialGradient>
<radialGradient id="darkBrownGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(0, 73%, 60%)" />
<stop offset="100%" stop-color="hsl(0, 73%, 20%)" />
</radialGradient>
<radialGradient id="starGradient"
gradientUnits="objectBoundingBox" fx="-1" fy="-1">
<stop offset="0%" stop-color="hsl(55, 87%, 100%)" />
<stop offset="100%" stop-color="hsl(55, 87%, 50%)" />
</radialGradient>
</defs>
<!-- You can see an example of polygon use at [1a] -->
<polygon fill="url(#starGradient)" stroke="black" stroke-width="10"
points="955,60 903,207 757,215 860,288 785,450
936,370 950,360 977,382 1061,437 1035,317 1111,225
1004,225" />
<polygon fill="url(#darkBrownGradient)" stroke="black" stroke-width="10"
points="950,360 936,370 931,476 830,554
880,554 1058,554
1105,554 973,476 977,382" />
<polygon fill="url(#greenTreeGradient)" stroke="black" stroke-width="10"
points="880,554
730, 1023 714, 1076
469, 2005 455, 2103
16, 3468 1, 3521
736, 3521 1184, 3521
2050, 3521
1800, 2634 1760, 2553
1357, 1464 1345, 1361
1058, 554" />
<polygon fill="url(#brownGradient)" stroke="black" stroke-width="10"
points="736,3521 736,3977 1184,3977 1184,3521" />
<polygon fill="url(#garlandGradient)" stroke="black" stroke-width="10"
points="
16,3468 1,3521
1800,2634 1760,2553
551,2055
1357,1464 1345,1361
730,1023 714,1076
1250,1430
469,2005 455,2103
1670,2630
" />
<!-- You can see examples of how to draw ellipses at 1c and
apply gradients at 1d -->
<ellipse cx="747" cy="1582" rx="50" ry="50"
fill="url(#blueCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="1220" cy="1990" rx="50" ry="100"
fill="url(#blueCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="545" cy="2950" rx="50" ry="50"
fill="url(#redCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="1248" cy="2600" rx="60" ry="60"
fill="url(#yellowCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="1013" cy="995" rx="40" ry="40"
fill="url(#yellowCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="1623" cy="3247" rx="50" ry="60"
fill="url(#redCircleGradient)" stroke="black"
stroke-width="10" />
<ellipse cx="642" cy="2600" rx="100" ry="80"
fill="url(#yellowCircleGradient)" stroke="black"
stroke-width="10" />
</g>
</svg>
This SVG Code will generate a tree that looks like this png:

In addition, if you have an SVG enabled browser like IE10 (or higher) you can see the actual rendering of the SVG file here:
In conclusion, there are a few advantages to the SVG File as opposed the PNG File:
- The SVG File is easily scalable
- The SVG File is easily changeble
- The SVG File weighs in at only 6K while the PNG file seems to take about 23K without the copyright
- The SVG File can be viewed with a plain text editor
- It would reasonably easy to use the SVG Tree in some kind of interactive
coloring program
(Unfortunately, I can't get into that in this post :-) )
It would be very difficult to get all of those benefits with a plain raster image. Now that you have amazingly tolorated this tutorial, I hope you have a better appreciation for the benefits of SVG and how to manully create SVG images. There are more techniques that can be applied to the image such as curves and blurs but those can be covered in other topics at a different time.
Bibliography
[1] - Various
Windows Metafile. Wikipedia.
[Online] DEC 14, 2013. [Cited: JAN 01, 2014.]
http://en.wikipedia.org/wiki/Windows_Metafile#Variants
[2] - Dahlström, Erik; Dengler, Patrick; Grasso, Anthony; Lilley, Chris;
McCormack, Cameron, Schepers, Doug; Watt, Jonathan; Ferrailolo, Jon;
藤沢 淳; Jackson, Dean
SVG 1.1 (Second Edition) - Basic Shapes. W3C.
[Online] AUG 16, 2011. [Cited: DEC 22, 2013.]
a) http://www.w3.org/TR/SVG
b) http://www.w3.org/TR/SVG/shapes.html#PolygonElement
c) http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace
d) http://www.w3.org/TR/SVG/shapes.html#CircleElement
e) http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
f) http://www.w3.org/TR/SVG/shapes.html#CircleElement
[3] - Coetzee, Derrick;
Converting PPT to SVG using Microsoft Office 2010 PIA.
Stack Overflow.
[Online] MAY 22, 2012. [Cited: JAN 01, 2013.]
http://stackoverflow.com/questions/5775060/converting-ppt-to-svg-using-microsoft-office-2010-pia
[4] - LePage, Pete.
How To: HSL and HSLA Color Models.
Pete LePage.com.
[Online] JUN 2010. [Cited: JAN 01, 2013.]
https://petelepage.com/blog/2010/07/how-to-hsl-and-hsla-color-models/
©2014 - Shawn and Kristen Grace Eary
This post and all images are copyright (where allowable) by Shawn and
Kristen Grace Eary and are released under the
Free Christian Document License (FCDL) and/or Free Christen Media License (FCML)
Content from authors other than Shawn Eary and Kristen Grace Eary maintain
the copyrights of their original authors.