如何保存完整的InkCanvas?

时间:2018-08-15 05:08:32

标签: c# wpf canvas

我正在尝试从InkCanvas保存图形。我还实现了缩放功能和滚动条,以增加InkCanvas的大小。保存的图片取决于缩放比例,即使大小是原始的,也不会保存完整的InkCanvas。

用于InkCanvas的XAML:

<ScrollViewer Grid.Row="2" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
    <Border x:Name="brd_borger"  MouseWheel="cnv_MouseWheel" Background="Aqua" Height="Auto" Width="Auto">
        <InkCanvas x:Name="cnv" Width="Auto" Height="Auto" Background="Aqua" 
               PreviewMouseLeftButtonDown="cnv_MouseLeftButtonDown"
               PreviewMouseRightButtonDown="cnv_MouseRightButtonDown" 
               SelectionChanged="cnv_SelectionChanged"
               SelectionMoving="cnv_SelectionMoving"
               SelectionMoved="cnv_SelectionMoved"

               EditingMode="None">

        </InkCanvas>
    </Border>
</ScrollViewer>

缩放代码:

private void cnv_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
        {
            var matrix = cnv.LayoutTransform.Value;

            if (e.Delta > 0)
            {
                matrix.ScaleAt(1.5, 1.5, e.GetPosition(this).X, e.GetPosition(this).Y);
            }
            else
            {
                matrix.ScaleAt(1.0/1.5, 1.0/1.5, e.GetPosition(this).X, e.GetPosition(this).Y);
            }

            cnv.LayoutTransform = new MatrixTransform(matrix);

        }
    }

保存代码:

private void Save_Click(object sender, RoutedEventArgs e)
    {
        SaveFileDialog dlg = new SaveFileDialog();
        dlg.DefaultExt = ".png";
        dlg.Filter = ODLG_FILTER_IMAGES;

        Nullable<bool> result = dlg.ShowDialog();

        if (result == true)
        {
            string filename = dlg.FileName;
            MemoryStream ms = new MemoryStream();
            FileStream fs = new FileStream(filename, FileMode.Create);

            RenderTargetBitmap rtb = new RenderTargetBitmap((int)cnv.Width, (int)cnv.Height, 96d, 96d, PixelFormats.Default);
            rtb.Render(cnv);
            BmpBitmapEncoder encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(rtb));

            encoder.Save(fs);
            fs.Close();

        }
    }

1 个答案:

答案 0 :(得分:0)

由于您不希望图像的大小与InkCanvas的实际大小相同,因此需要在实际位置指定实际的目标图像大小。然后,您可以使用DrawingContextVisualBrush来创建图像:

private void Save_Click(object sender, RoutedEventArgs e)
{
    SaveFileDialog dlg = new SaveFileDialog();
    dlg.DefaultExt = ".png";
    dlg.Filter = ODLG_FILTER_IMAGES;

    if (dlg.ShowDialog() == true)
    {
        string filename = dlg.FileName;
        MemoryStream ms = new MemoryStream();
        FileStream fs = new FileStream(filename, FileMode.Create);

        //define your image size here...
        const int Width = 200;
        const int Height = 200;
        RenderTargetBitmap rtb = new RenderTargetBitmap(Width, Height, 96d, 96d, PixelFormats.Default);
        Rect bounds = VisualTreeHelper.GetDescendantBounds(cnv);
        DrawingVisual dv = new DrawingVisual();
        using (DrawingContext ctx = dv.RenderOpen())
        {
            VisualBrush vb = new VisualBrush(cnv);
            ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
        }

        rtb.Render(dv); ;
        BmpBitmapEncoder encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(rtb));

        encoder.Save(fs);
        fs.Close();
    }
}