将WPF画布保存在不失去质量的情况下(不使用位图作为中介)



我的任务是为某些动态制冷剂属性创建列表。(诺克示例)。具体来说,我必须创建一个程序,该程序获取用户输入,然后生成可打印的notograph图形。我必须与几个外部BlackBox .dll接口以获取一些数据,因此我认为.NET是我使用的最佳平台。看到没有现有工具可以轻松地借给创建所有4个轴都基于用户输入的非常复杂的图形,因此我已经构建了它以在WPF帆布上绘制线条和文本。一切都很好;放大,平移等等。我有一个问题。

我发现将WPF画布保存到文件(例如PNG)的每个答案都使用了位图作为到达那里的路线。此问题的问题是,我已经尝试了它并使其工作起作用,这是结果的图像将失去所有可扩展性,并且取决于画布的大小,质量很大。XAML应该是所有矢量图形,并且由于这是一个图形,其中包含大量信息到一个小区域,所以我需要一个可扩展的结果。

注意:这是不是 所有其他"如何将wpf画布保存到提交"问题的重复。

我尝试过的事情:

  1. 所有其他"如何将WPF画布保存到文件"答案。
  2. RenderTargetBitmap()方法中增加DPI输入。(注意:这只是将图像放大到上左角的角落,使其无法使用)

想法

我认为,也许如果没有办法做我要问的事情,那也可以起作用的事情只是将画布及其所有子元素缩放在保存之前,可能会缩放到荒谬的东西上,也许是制作副本,然后保存该元素?事实是,我根本不确定该如何做到这一点,我宁愿看看是否有一种方法可以先保存到矢量图形。

这是我的XAML:

<Window x:Class="RefGraph.Graph"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:RefGraph"
    mc:Ignorable="d"
    Title="Graph" Height="1081" Width="1400">
<Grid>
    <Viewbox>
        <Canvas Height="{Binding Path=CanvasHeight}" Width="{Binding Path=CanvasWidth}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,20,0,0" MouseWheel="Canvas_MouseWheel" MouseMove="Canvas_MouseMove" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp">
            <Canvas.RenderTransform>
                <TransformGroup>
                    <TranslateTransform/>
                    <MatrixTransform/>
                </TransformGroup>
            </Canvas.RenderTransform>
            <ContentPresenter Content="{Binding Canvas}"></ContentPresenter>
        </Canvas>
    </Viewbox>
    <Menu x:Name="Menu_Main" Width="{Binding ActualWidth, ElementName=DockPanel_Menu}" Height="20" VerticalAlignment="Top">
        <MenuItem x:Name="Menu_File" Header="_File">
            <MenuItem x:Name="MenuItem_Save" Header="_Save" InputGestureText="Ctrl+S" VerticalAlignment="Top" HorizontalAlignment="Left" Click="MenuItem_Save_Click"/>
            <MenuItem x:Name="MenuItem_SaveAs" Header="_Save As" InputGestureText="Ctrl+Shift+S" VerticalAlignment="Top" HorizontalAlignment="Left" />
            <MenuItem x:Name="MenuItem_Print" Header="_Print" InputGestureText="Ctrl+P" VerticalAlignment="Top" HorizontalAlignment="Left" />
            <MenuItem x:Name="MenuItem_PrintPreview" Header="_Print Preview" InputGestureText="Ctrl+Shift+P" VerticalAlignment="Top" HorizontalAlignment="Left"/>
            <Separator />
            <MenuItem Header="_Exit" InputGestureText="Ctrl+X" VerticalAlignment="Top" HorizontalAlignment="Left" />
            </MenuItem>
    </Menu>
</Grid>
</Window>

我应该注意,保存之前有许多孩子元素会动态添加到画布中。

另一个注意事项:由于某种原因,我认为PNG是向量图形。老实说,我不知道为什么。我想这个问题不是专门关于PNG的,而是更多关于在没有质量糟糕的情况下保存画布的更多信息,这是使用本网站上的现有答案所必需的。我已经编辑了这个问题以反映这一点,并且也发布了答案。

要将画布或大多数其他XAML元素保存到PDF,您需要参考呈现frameframework和system.printing。

然后,您可以创建一个PrintDialog,设置您想要的任何首选项,然后使用它保存到PDF。

void SaveCanvasToPDF(Canvas myCanvas){
    PrintDialog pd = new PrintDialog();
    pd.PrintQueue = new PrintQueue(new PrintServer(), "Microsoft Print to PDF");
    pd.PrintTicket.PageOrientation = PageOrientation.Landscape;
    pd.PrintTicket.PageScalingFactor = 100;
    pd.PrintVisual(myCanvas, "Nomograph");
}

因为您在谈论图像的清晰度。您能否尝试将现有的WPF画布转换为SVG(可扩展的向量图形)文件。我没有尝试过。希望以下链接对您有所帮助。

https://archive.codeplex.com/?p=svg

https://github.com/vvvv/svg

最新更新