High-Resolution Printing of WPF 3D Visuals
December 7, 2007
Roscoe, N.Y.
I received an email from a reader of 3D-Programmierung für Windows (the German translation of 3D Programming for Windows) about printing scenes composed in WPF 3D.
Some background: In the last chapter of my book (entitled "Applications and Curiosa") I discuss two ways of printing WPF 3D scenes. Both involve the handy PrintVisual method of PrintDialog. Because PrintVisual accepts any object created from a class that derives from Visual, you can print elements such as Viewport3D. However, you generally have more control over the size and placement of the printed image if you instead print objects of type Viewport3DVisual, a class that derives directly from Visual.
Regardless which way you do it, you get jaggies. Apparently WPF 3D scenes always print at 96 DPI. I don't know why this is, but I suppose there's a good reason for it.
My reader in Germany wasn't happy about that and wondered if there's a solution.
More background: When writing 3D Programming for Windows I created many of the visuals from XAML files rendered on a RenderTargetBitmap. When you create such a bitmap, you can specify both the pixel size and the bitmap resolution in dots per inch. This technique allows you to create higher resolution images than you get by the customary screen-shot method, which involves capturing the actual screen image in a bitmap at screen resolution.
I wondered if I could apply that technique to printing: Rather than pass the Viewport3DVisual to the PrintVisual method, first create a RenderTargetBitmap at 300 DPI and call the Render method to render the Viewport3DVisual on the bitmap. Then put the bitmap in an Image element, subject it to a layout pass by calling Measure and Arrange, and pass the Image element to the PrintVisual method.
It worked! Here's the enhanced PrintViewport3DVisual project with two menu items for Normal printing and Hi-Res printing for comparison.