将 InkCanvas 保存到字节数组到文件时图像被损坏

Image gets mangled when saving InkCanvas to byte array to file

我有一个使用 InkCanvas 的 WPF 应用程序。当我渲染位图,保存到内存流,将生成的字节写入文件,然后在 Paint 中打开该文件时,图像被破坏了。知道我在这里做错了什么吗?尝试了在 SO 和 codeproject 上找到的几种解决方案。很明显它捕获了 InkCanvas 的一部分,但其中大部分是黑色的(我假设是空字节)。

编辑:也尝试了 with/without 保证金。这是我试过的其他链接:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/ef71237c-5dfb-4d6c-a402-e8cb02b74e99/how-to-convert-inkcanvas-strokes-to-a-bitmap-or-byte-array?forum=wpf

InkCanvas Load/Save operations

http://www.centrolutions.com/Blog/post/2008/12/09/Convert-WPF-InkCanvas-to-Bitmap.aspx

https://social.msdn.microsoft.com/Forums/vstudio/en-US/ba4dc89f-0169-43a9-8374-68e1fb34a222/saving-inkcanvas-as-image?forum=wpf

我需要生成的文件是 bitmap/PNG 以便可以在另一台机器上查看。

private byte[] ConvertInkCanvasToByteArray()
{ 
    int margin = (int)this.icSignature.Margin.Left;
    int width = (int)this.icSignature.ActualWidth - margin;
    int height = (int)this.icSignature.ActualHeight - margin;

    RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
    rtb.Render(icSignature);

    BmpBitmapEncoder encoder = new BmpBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));
    byte[] bitmapBytes;
    using (MemoryStream ms = new MemoryStream())
    {
        encoder.Save(ms); 
        ms.Position = 0;
        bitmapBytes = ms.ToArray();
    }
    return bitmapBytes;
}

来自 InkCanvas:

然后被破坏:

为避免 InkCanvas 的边距出现任何问题,您可以将其绘制到中间 DrawingVisual 中:

private byte[] ConvertInkCanvasToByteArray()
{
    var rect = new Rect(icSignature.RenderSize);
    var visual = new DrawingVisual();

    using (var dc = visual.RenderOpen())
    {
        dc.DrawRectangle(new VisualBrush(icSignature), null, rect);
    }

    var rtb = new RenderTargetBitmap(
        (int)rect.Width, (int)rect.Height, 96d, 96d, PixelFormats.Default);
    rtb.Render(visual);

    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));

    using (var stream = new MemoryStream())
    {
        encoder.Save(stream);
        return stream.ToArray();
    }
}