从具有LiveChart的UserControl渲染图像 [英] Render image from UserControl that has LiveChart

查看:155
本文介绍了从具有LiveChart的UserControl渲染图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在渲染未在窗口中显示的UserControl的黑色/空白图像. UserControl包含LiveChart的CartesianChart和几个UIElement.首先,我从> C#图表到带有LiveCharts的图表中借用了解决方案

I kept rendering a black/blank image of a UserControl not shown in window. The UserControl contains LiveChart's CartesianChart and few UIElements. First I borrowed solutions from SO: C# chart to image with LiveCharts and Github: Live-Charts/ChartToImageSample.xaml.cs and apply SaveToPng and EncodeVisual on a simple UIControl generated in runtime (not added or shown in window), which works.

Canvas control = new Canvas() { Width=100, Height=100, Background = new SolidColorBrush(Colors.Pink)};
control.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
control.Arrange(new Rect(0, 0, control.DesiredSize.Width, control.DesiredSize.Height));
control.UpdateLayout();
SaveToPng(control, @"C:\Foo.png");

private void SaveToPng(FrameworkElement visual, string fileName)
{
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    EncodeVisual(visual, fileName, encoder);
}

private static void EncodeVisual(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32);
    bitmap.Render(visual);
    BitmapFrame frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);
    using (FileStream stream = File.Create(fileName)) encoder.Save(stream);
}

但是当我将相同的逻辑应用于UserControl

But when I applied the same logic to a UserControl

UserControl control = new UserControl(params)
// canvas.Children.Add(control);  <-- if comment out, output blank/black image
control.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
control.Arrange(new Rect(0, 0, control.DesiredSize.Width, control.DesiredSize.Height));
foreach (CartesianChart cc in FindVisualChildren<CartesianChart>(control))
{
    cc.Update(true, true); //force chart redraw
}
control.UpdateLayout();
SaveToPng(control, @"C:\Foo.png");

<!-- UserControl XAML -->
<UserControl>
   <Grid>
      <Border>
         <Grid>
            <Label></Label>
            <Label></Label>
            <Label></Label>
            <CartesianChart DisableAnimations="True"></CartesianChart>
         </Grid>
      </Border>
   </Grid>
</UserControl>

输出空白/黑色图像.并且只有当我将UserControl添加到存在于窗口/XAML中且在窗口/XAML中可见的UIControl中时,UserControl才能正确呈现到图像(例如canvas.Children.Add(lc)).然后,我还尝试了

That output a blank/black image. And only when I add UserControl into a UIControl existed and visible on the window/XAML will the UserControl gets rendered properly to an image (e.g. canvas.Children.Add(lc)). I then also tried the solution described in SO: How to render a WPF UserControl to a bitmap without creating a window, but I get the identical result - that is I need to first add this UserControl to a visible UIControl, whether or not I perform UpdateLayout on the UserControl.

为什么要渲染第一个示例(画布),而不渲染第二个示例(UserControl)?有什么区别,我该如何解决?

Why the first example (Canvas) gets rendered, but not the second example (UserControl)? What are the difference and how can I fix this?

推荐答案

对我来说,这仅适用于图表以及整个用户控件: (注意:请确保您的用户控件具有可见的背景颜色,如果背景是透明的,则它将变为透明,大多数图像查看器都显示为黑色)

For me this works fine for only the chart as well as for the whole user control: (Note: be sure your usercontrol has a visible background color, if the background is transparent it will be rendered transparent which most image viewer show as black)

好的,如果图表不可见,我想我的解决方案将无法工作.但是,如果您无法使其正常工作,为什么不在新窗口中显示该用户控件,将其保存并再次关闭该窗口呢?

ok, I guess my solution won't work if the chart isn't visible. But if you can't get it to work otherwise, why not show the usercontrol in a new window, save it and close that window again?

    public static BitmapSource RenderChartAsImage(FrameworkElement chart)
    {
        RenderTargetBitmap image = new RenderTargetBitmap((int)chart.ActualWidth, (int)chart.ActualHeight,
                                                            96, 96, PixelFormats.Pbgra32);
        image.Render(chart);
        return image;
    }

    public static void SaveChartImage(FrameworkElement chart)
    {
        System.Windows.Media.Imaging.BitmapSource bitmap = RenderChartAsImage(chart);

        Microsoft.Win32.SaveFileDialog saveDialog = new Microsoft.Win32.SaveFileDialog();
        saveDialog.FileName += "mychart";
        saveDialog.DefaultExt = ".png";
        saveDialog.Filter = "Image (*.png)|*.png";

        if (saveDialog.ShowDialog() == true)
        {
            using (FileStream stream = File.Create(saveDialog.FileName))
            {
                System.Windows.Media.Imaging.PngBitmapEncoder encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
                encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bitmap));
                encoder.Save(stream);
            }
        }
    }

这篇关于从具有LiveChart的UserControl渲染图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆