How to render a WPF UserControl to a bitmap without creating a window

后端 未结 4 946
梦谈多话
梦谈多话 2020-11-27 04:27

How can I render a WPF UserControl to a bitmap without creating a window? I need to render a WPF UserControl and upload it to another program. The bitmaps will be rendered t

相关标签:
4条回答
  • 2020-11-27 04:36

    Apparently, if you call control.UpdateLayout() after measuring and arranging, the user control doesn't need to be in any window.

    0 讨论(0)
  • 2020-11-27 04:40

    Based on IDWMaster's solution I did it a bit differently using the System.Windows.Forms.UserControl. Otherwise the bindings were not up-to-date when the export to bitmap happened. This works for me (this is the WPF control to render):

    System.Windows.Forms.UserControl controlContainer = new System.Windows.Forms.UserControl();
    controlContainer.Width = width;
    controlContainer.Height = height;
    controlContainer.Load += delegate(object sender, EventArgs e)
    {
        this.Dispatcher.BeginInvoke((Action)delegate
        {
            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
                bmp.Render(this);
                BitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bmp));
                encoder.Save(fs);
                controlContainer.Dispose();
            }
        }, DispatcherPriority.Background);
    };
    
    controlContainer.Controls.Add(new ElementHost() { Child = this, Dock = System.Windows.Forms.DockStyle.Fill });
    IntPtr handle = controlContainer.Handle;
    
    0 讨论(0)
  • 2020-11-27 04:51

    Have you tried spinning up an instance of the user control and doing something like this:

    UserControl control = new UserControl1();
    
    control.Measure(new Size(300, 300));
    control.Arrange(new Rect(new Size(300,300)));
    
    RenderTargetBitmap bmp = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Pbgra32);
    
    bmp.Render(control);
    
    var encoder = new PngBitmapEncoder();
    
    encoder.Frames.Add(BitmapFrame.Create(bmp));
    
    using (Stream stm = File.Create(@"c:\test.png"))
       encoder.Save(stm);
    

    It looks like you need to Measure, Arrange. This worked for me.

    0 讨论(0)
  • 2020-11-27 04:58

    Ended up using an HwndHost with no actual window.

    void cwind()
        {
            Application myapp = new Application();
            mrenderer = new WPFRenderer();
            mrenderer.Width = 256;
            mrenderer.Height = 256;
    
            HwndSourceParameters myparms = new HwndSourceParameters();
            HwndSource msrc = new HwndSource(myparms);
            myparms.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);
    
            msrc.RootVisual = mrenderer;
            myapp.Run();
        }
        static IntPtr ApplicationMessageFilter(
    IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            return IntPtr.Zero;
        }
    
    0 讨论(0)
提交回复
热议问题