Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Plots area is empty(Lost waveform) when save NI Graph by RenderTargetBitmap in Window_ContentRendered event

Solved!
Go to solution

Hi Experts,

 

Recently we have a request to create screenshots of waveforms, we implement this with WPF RenderTargetBitmap to save the graph grid to a image file. Since we have a lot of waveforms to save, so in a loop, we set the DataSource of the viewmodel each time and show the window, then in the window's Window_ContentRendered event to save the grap image. But the problem is that, when the data source is large, for example, 4 channels with 1M ponits of each channel, some of the generated image file lost the plot area. See the attached pictures.

Lost waveformLost waveformCorrect display waveformCorrect display waveform

Here is the code we use the graph:

XAML.PNG

<ni:Graph Name="graph" HorizontalAlignment="Stretch" Margin="0" DataSource="{Binding DataSource}" VerticalAlignment="Stretch" Cursor="Arrow" DataProcessed="graph_DataProcessed">
<ni:Graph.Axes>
<ni:AxisDouble x:Name="horizontalAxis" Orientation="Horizontal" Range="{Binding Xrange,Mode=TwoWay}" Adjuster="None">
</ni:AxisDouble>
</ni:Graph.Axes>
</ni:Graph>

 

And here is how we handle the Window_ContentRendered event:

        private void Window_ContentRendered(object sender, EventArgs e)
        {
            double width = Convert.ToInt32(this.MainGrid.ActualWidth);
            double height = Convert.ToInt32(this.MainGrid.ActualHeight);
            double dpi = 300;
            double scale = dpi / 96;

            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                var rtb = new RenderTargetBitmap((int)(width * scale), (int)(height * scale), dpi, dpi, System.Windows.Media.PixelFormats.Default);
                rtb.Render(this.MainGrid);
                var bit = ImageHandler.BitmapSourceToBitmap(rtb);
                bit.Save(_screenShotFile);
                bit.Dispose();
                this.Close();
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
            }),DispatcherPriority.ContextIdle,null);
        }

 
Usually, when the datasource is 4*1M, we have about 10 images lost every 100 pictures, if the data source is 4*100k, only few lost images. But on some old machines, even 4*100k will also lost about 20% images.

 

According to my understanding, when the window_contentRendered event is triggered, the NI Graph should already complete rendering the image, I don't know why we lost the waveforms when saving to image file. Is there any other event I should use to save the WPF Grid as a image? Thanks in advance.

0 Kudos
Message 1 of 4
(175 Views)
Solution
Accepted by topic author JackieXu

I won't have a chance to investigate until next week, but you might try disabling background processing to ensure the graph displays all values synchronously:

 

<ni:Graph
    niPrimitives:GraphConfiguration.UseBackgroundProcessing="False"
    niPrimitives:GraphConfiguration.UseBackgroundRendering="False"
    ...

 

 

Alternatively, you might want to wait until both Window_ContentRendered and graph_DataProcessed events have fired before trying to save the image.

~ Paul H
0 Kudos
Message 2 of 4
(149 Views)

Hi Paul,

 

Many thanks for your reply, I will try it tomorrow when I have the online machine.

0 Kudos
Message 3 of 4
(117 Views)

It works, thanks a lot, you saved me.

0 Kudos
Message 4 of 4
(95 Views)