The motive for smaller image size is evident: faster download time. But how low can you go? Inkscape is an OpenSource drawing program which you can download for free. It has a brilliant feature to convert bitmap images (PNG’s) to vector graphics. Silverlight used to advertise that vector graphics have higher quality as you can zoom in without quality loss. This is true, however PNG’s and vector graphics are not very well exchangeable.
I took the following steps to convert a PNG to vector graphics:
- Import PNG from the File menu;
- Convert it to vector graphics, Trace Bitmap in the Path menu. Select “Colors”, Scans=12, Remove Background checked. Click Update then click OK.
- Reduce vector points, Simplify in Path menu;
- Save as XAML, File menu;
This is the result in Inkscape:
The left is the original, the right is converted to vector graphics and Simplified only once. Now obviously, there is quite some quality loss in the vector representation. We deal with quality later, this article is about file size.
Open the resulting XAML in Visual Studio. Now go to the Edit menu, Advanced, Format Document. Remove empty tags “Resources” and “RenderTransform”. Remove the “<?xml” line at the top. This result can be copied into a new Silverlight UserControl.
If the new UserControl is now compiled, the resulting binary is larger in file size than the original PNG you started with. The reason for this is that Visual Studio does not convert XAML to binary code. If you open a Silverlight binary in for example Notepad, you will notice that a complete copy of the original XAML is somewhere within the dll. In most cases, text is larger in size than the binary equivalent.
Compression 1: text-float to binary float
The Path geometry data from your Inkscape XAML contains many floating point numbers, in text representation, while a binary float is only 4 bytes long. As these floats occupy the larger part of the Inkscape XAML, we could write a little program to convert this Inkscape result into something binary.
Well, that is what I did experimentally. And although this converter does not support the full Path data mini-language yet, the lion-part is already converted to a binary representation. And if you have the lion-part, then there is a good moment to determine whether your experiment will ever have any success: get smaller file sizes.
These are my findings:
The original PNG is 16KB. The product from Inkscape is 50KB. This will also be the size when you compile the UserControl. When zipping this to a xap will never be better than the original 16KB.
Converting the Path textual data to binary .Net floats, the product is now 22Kb (the .XZ file). When adding more features to the converter, this size will be a little larger; I estimate about 1Kb, because these features are rarely used.
The next step is to look at the size of the XZ file when zipped: 11Kb. Zipping the original PNG will result in a zipfile with the same size. So with this immature and still-under-development compression technique, we already gain 35% in filesize.
Compression 2: text-float to binary short
I also tested another technique for further compression. Float’s are 4 bytes long, while shorts are 2 bytes long. A technique learned from the past: multiply the float with a factor to gain precision, and cast it to short to discard remaining precision. Evaluation of this technique is out of scope here. The result is however that a number no longer occupies 4 bytes, but only 2 bytes.
To only know the results of this technique, I did a test, having factor = 100. These are my findings:
The XZ file, the result of my compression program, is 12KB, already smaller than the original PNG. Compressed, the XZ file is only 6KB, giving a gain of 62%.
Now, let’s not get too excited. I have cheated this discussion on two important points. Yes I have converted the Inkscape XAML to a binary representation, but I never decompressed it. I don’t know what the results will be when I decompress the XZ file and construct a UserControl in my Silverlight application. It could turn out to look very bad. This is the next research step.
Secondly, after I converted the PNG to vector graphics, I used the Simplify function in Inkscape, to decrease the amount of floats in the resulting XAML. How far does this Simplify step affect the compression results? Well, quite a bit.
This is the result of converting PNG to vector graphics, without simplify function:
Here are the compression results for text-float to float:
And here are the compression results for text-float to short:
So when it is forbidden to use Inkscape’s simplify function, the conclusion is that the compression 1 method is not worth implementing, while the compression 2 method is worth investigating.
Ofcourse it is not forbidden to use the simplify function. You can even create graphics which anticipate this function in the art process.