Archive for the ‘XAML’ Category

C# .Net – Render XAML to Image

April 26, 2010

I’ve been trying to find a way to render XAML to PDF or SVG but I’ve had no luck in finding code examples on how to do this. So, for the moment I’ve resorted to rendering XAML to an Image.

Here are the code snippets that I came up with do the job. This code requires .Net Framework 3.5 or later.

Please leave comments if you know how to get from XAML to PDF via an API. I would be really grateful.

public static Stream XamlToImageSteam(
    XmlTextReader xmlReader, BitmapEncoder encoder, Stream outputStream,
    double dpiX, double dpiY ) {

    Window wind = new Window();
    wind.WindowStyle = WindowStyle.None;
    wind.ShowInTaskbar = false;
    wind.ShowActivated = false;

    // Create Minimized so the window does not show. wind.WindowState = System.Windows.WindowState.Minimized;
    wind.SizeToContent = SizeToContent.WidthAndHeight;

    wind.Content = (UIElement)XamlReader.Load(xmlReader);
    wind.Show(); // The window needs to be created for the XAML elements to be rendered. BitmapSource bitmapSrc = visualToBitmap(wind, dpiX, dpiY);

    encoder.Frames.Clear();
    encoder.Frames.Add(BitmapFrame.Create(bitmapSrc));
    encoder.Save(outputStream);

    outputStream.Flush();

    wind.Hide();
    return outputStream;
}
static BitmapSource visualToBitmap( Visual target, double dpiX, double dpiY ) {
    if (target == null) return null;

    Rect bounds = VisualTreeHelper.GetDescendantBounds(target);

    int width = (int)(bounds.Width * dpiX / 96.0);
    int height = (int)(bounds.Height * dpiX / 96.0);

    RenderTargetBitmap renderer = new RenderTargetBitmap(
            width, height, dpiX,
            dpiY, PixelFormats.Pbgra32);

    renderer.Render(target);

    return renderer;
}

Here is an example of rendering some XAML to a png image:-

double dpiX = 96.0;
double dpiY = 96.0;

string xaml =
    "<Page\r\n" +
    " xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\r\n" +
    " xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\r\n" +
    " <Canvas>\r\n" +
    " <Rectangle Width=\"220\" Height=\"100\"\r\n" +
    " RadiusX=\"10\" RadiusY=\"10\" Fill=\"#90d0ff\"/>\r\n" +
    " <TextBlock Canvas.Left=\"25\" Canvas.Top=\"25\"\r\n" +
    " FontSize=\"16\" Foreground=\"White\">Mike Coxeter's .Net Blog</TextBlock>\r\n" +
    " <TextBlock Opacity=\".5\" Canvas.Left=\"26\" Canvas.Top=\"50\"\r\n" +
    " FontSize=\"16\" Foreground=\"White\" >C#, .Net, WPF</TextBlock>\r\n" +
    " </Canvas>\r\n" +
    "</Page>";

XmlTextReader xmlReader = new XmlTextReader(new StringReader(xaml));
using (Stream imageStream = File.Create(@"c:\dotNetBlog.png")) {
    XamlToImageSteam(xmlReader, new PngBitmapEncoder(), imageStream, dpiX, dpiY);
}

dotNetBlog Image produced from above Example
Advertisements