Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render a "not visible" WPF controls to an bitmap image

Tags:

bitmap

wpf

render

Render a WPF control to a bitmap image is not a trivial task as I found out today. As I know now dealing with the parent control margin is a problem, as Rick Strahl wrote in his blog

http://www.west-wind.com/weblog/posts/2007/Sep/10/Rendering-a-WPF-Container-to-Bitmap

So far I am able to create bitmaps of any control that is visible inside a window but what I really need to do is create bitmaps of invisible controls. I just create them in code - simples shapes like rectangle and ellipse - and want to save them as bitmaps to disk. For me this turn out to be a personal nightmare. Since my ActualHeight and ActualWidth is always 0 I use Height and Width instead. But all I get is a empty image in the size of my control.

How can I create a bitmap of any control without adding it to a visible window?

like image 625
TalkingCode Avatar asked May 03 '11 11:05

TalkingCode


1 Answers

New elements haven't had their layout performed. You need to call Measure and Arrange on the control before you render it.

Canvas c = new Canvas();

Rectangle r = new Rectangle
{
    Fill = Brushes.Orange,
    Width = 200,
    Height = 100
};

Ellipse e = new Ellipse
{
    Fill = Brushes.DodgerBlue,
    Width = 100,
    Height = 100
};

Canvas.SetLeft(e, 150);

c.Children.Add(r);
c.Children.Add(e);

var size = new Size(250,100);
c.Measure(size);
c.Arrange(new Rect(size));

RenderTargetBitmap bmp = new RenderTargetBitmap(250, 100, 96, 96, PixelFormats.Pbgra32);

bmp.Render(c);

PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bmp));

using(var s = File.OpenWrite("image.png"))
    enc.Save(s);
like image 171
Kris Avatar answered Nov 16 '22 02:11

Kris