Сохранение WPF Canvas в файл без потери качества (без использования растрового изображения в качестве посредника) - PullRequest
0 голосов
/ 18 декабря 2018

Мне было поручено создать номограммы для некоторых динамических свойств хладагента.( Примеры номографов ).В частности, я должен создать программу, которая принимает пользовательский ввод, а затем генерирует печатную графику номограммы.Я должен взаимодействовать с парой внешних .dll черного ящика, чтобы получить некоторые данные, поэтому я решил, что .NET была лучшей платформой для меня.Поскольку не существует никакого существующего инструмента, который бы легко создавал очень сложные графики, где все 4 оси основаны на пользовательском вводе, я построил его так, чтобы просто рисовать линии и текст на холсте WPF.Все работает отлично;Масштабирование, панорамирование, все это.Однако у меня есть одна проблема.

Каждый найденный мной ответ на вопрос о сохранении холста WPF в файл, такой как png, использовал растровое изображение в качестве маршрута, чтобы добраться туда.Проблема с этим, и я попробовал и заставил его работать, состоит в том, что получающееся изображение теряет всю масштабируемость и, в зависимости от размера холста, большое качество.XAML должен быть всей векторной графикой, и поскольку это график с большим количеством информации, упакованной в небольшую область, мне нужен масштабируемый результат.

ПРИМЕЧАНИЕ. Это НЕ , дубликатна все остальные вопросы «Как сохранить холст WPF в файл».

Вещи, которые я пробовал:

  1. На все остальные ответы «Как сохранить холст WPF в файл».
  2. Увеличение значения dpi в методе RenderTargetBitmap().(ПРИМЕЧАНИЕ: это просто увеличивает изображение в верхнем левом углу, делая его непригодным для использования)

Идеи

Я думаю, может быть, если нет способа сделать то, что я спрашиваю,что-то, что также может сработать, - это просто масштабировать холст и все его дочерние элементы до чего-то смехотворно большого перед сохранением, может быть, сделать копию, а затем сохранить это?Правда в том, что я совсем не уверен, как это сделать, и я лучше посмотрю, есть ли способ сначала сохранить в векторную графику.

Вот мой 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, а скорее сохранения холста без ужасного качества, что было бы необходимо при использовании существующих ответов на этом сайте.Я отредактировал вопрос, чтобы отразить это, и я также опубликовал ответ.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Чтобы сохранить Canvas или большинство других элементов XAML в PDF, вам нужна ссылка на PresentationFramework, а также на 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");
}
0 голосов
/ 18 декабря 2018

Поскольку речь идет о четкости изображения.Не могли бы вы попытаться преобразовать существующий WPF Canvas в файл SVG (Scalable Vector Graphics).Я не пробовал это.Надеюсь, что ссылка ниже поможет вам.

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

https://github.com/vvvv/SVG

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...