-
Notifications
You must be signed in to change notification settings - Fork 980
Description
Description
To export whole plot pages (like paper pages) as PNG we create a new ViewModel in our MVVM WPF application only for the export which is not displayed on the screen. We don't use the oxyplot pngexporter for this because the pages contains also textboxes and other elements.
After updating to the latest OxyPlot version and switching to SkiaSharp Render, this no longer works.
We get a NullreferenceException when exporting.
Steps to reproduce
Create and render a PlotView with code like this:
var mainGrid = new Grid() { Height = 400, Width = 600 };
mainGrid.Children.Add(new PlotView() { Model = plotModel });
var bmp = FrameworkElementToBitmap(mainGrid);
WritePngToFile(@"ExportTestSkiaRenderer.png", bmp);
Use a RenderTargetBitmap to render it as an image.
private static BitmapSource FrameworkElementToBitmap(FrameworkElement frameworkElement)
{
var size = new Size(frameworkElement.Width , frameworkElement.Height );
frameworkElement.Measure(size);
frameworkElement.Arrange(new Rect(size));
frameworkElement.UpdateLayout();
var bmp = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96.0, 96.0, PixelFormats.Pbgra32);
bmp.Render(frameworkElement);
return bmp;
}
private void WritePngToFile(string fileName, BitmapSource bitmapImage)
{
using (var fileStream = File.Create(fileName))
using (var pngStream = new MemoryStream())
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
encoder.Save(pngStream);
pngStream.WriteTo(fileStream);
}
}
This causes a NullReferenceException at:
var m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
scaleX = m.M11;
scaleY = m.M22;
and at
// get window to screen offset
var visualOffset = this.TransformToAncestor(GetAncestorWindowFromVisualTree(this)).Transform(default);
Platform: x86 & x64
.NET version: 4.7.2
Latest OxyPlot Version (nuget packages build from develop brunch)
Expected behaviour
Rendering should be possible as in older versions.
Version f9cebf3 from 2019-01-31 didn't have this issue.
Actual behaviour
When exporting as described above we get a NullreferenceException.
Possible Fix
Return the default value if the PresentationSource or the ancestor visual is null:
var compositionTarget = PresentationSource.FromVisual(this)?.CompositionTarget;
if (compositionTarget != null)
{
var m = compositionTarget.TransformToDevice;
scaleX = m.M11;
scaleY = m.M22;
}
and
// get window to screen offset
var ancestor = GetAncestorWindowFromVisualTree(this);
var visualOffset = ancestor!=null ? this.TransformToAncestor(ancestor).Transform(default) : default;