I've made some progress with the image replacement solution for ASP.NET since the first beta. Morgan Skinner, whose name should be well known to MSDN Magazine subscribers, pointed me to his article on quantization. With his code doing post-processing of dynamically generated images I can proudly say this is looking much much better! Hats off to Morgan!
I've made some changes to the code now in beta 2 (shall we give it a goofy name along the lines of "Whidbey"?)
- The source code includes Morgan's
Quantizer and OctreeQuantizer classes. If you're curious how Octree-based Quantization works, see his article.
- The image handler produces GIFs, not JPEGs. Empirically I figured out the combination of GIF + quantization renders much cleaner images.
- There was a bug with
StringFormat.GenericDefault. With certain font sizes the text gets clipped. Seems like the algo computes the image width correctly, but chops it when painting. StringFormat.GenericTypographic handles it correctly.
Use Your Own Font Files
Since my hosting company has a poor selection of fonts on their servers (and why would they need more?) I wanted to be able to load a font from a file. It's possible to do it with a PrivateFontCollection object like this:
PrivateFontCollection
privateFontCollection = new PrivateFontCollection();
privateFontCollection.AddFontFile (
ctx.Request.PhysicalApplicationPath + fontFace);
where fontFace is the name of a file with an extension. For example, with the sample code you'll find Book Antiqua in file bkant.ttf. In your HTML you'll specify it as follows:
dotIR.replaceElement (
"h1", "#990000", "#ccc", 495, "left", 42, "bkant.ttf")
The image handler looks for a font file in the root of your web app.
This is where I hit a snag. What about OpenType fonts? A search in newsgroups revealed that GDI+ doesn't support them. I mean, it does. Partially. It will load a .otf file as long as it has TrueType outlines, not PostScript ones.
What's even stranger GDI does seem to support them, but GDI+ doesn't. The advice I found was to resort to PInvoke to call GDI if you really wanted to load OpenType fonts. At this point I think it will be an overkill, so .ttf files it is for now.
Loaded or Not... Here I Come!
There's a strange issue which I don't know how to deal with. Internet Explorer/Windows thinks it's not done downloading dynamically generated images. Mozilla and Opera "get it" fine. In IE, though, you see a progress indicator on the bottom even though the image handler is done streaming!
This is not the first time I generate images on the fly, but this time around it sure is weird. Every code sample I've seen does it in two lines:
ctx.Response.ContentType = "image/gif";
quantizedBitmap.Save (ctx.Response.OutputStream, ImageFormat.Gif);
Somebody tell me what's missing here. What is IE missing?
Grab It While It's Hot
The source code of beta 2 is available for download. Please let me know of any bugs and suggest improvements.