wpf - 如何将 System.Windows.Media.DrawingImage 转换为 Stream?

标签 wpf bitmap memorystream

我正在尝试将 DrawingImage 转换为 MemoryStream。我的代码如下所示:

public MemoryStream ImageStream(DrawingImage drawingImage)
    {
        MemoryStream stream = new MemoryStream();
        ImageSource imageSource = drawingImage;
        if (imageSource != null)
        {
            BitmapSource bitmap = imageSource as BitmapSource;
            if (bitmap != null)
            {
                BitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bitmap));
                encoder.Save(stream);
            }     
        }

        return stream;
    }

但问题是在将 ImageSource 转换为 BitmapSource 位图后始终为空。任何建议如何解决?

最佳答案

您的 bitmap 变量始终为 null 的原因是因为 DrawingImage 没有扩展 BitmapImage 或反之亦然,因此可以保证转换失败。 DrawingImage 不包含任何类型的像素数据。它引用了一个 Drawing,只要图像需要被栅格化就会被使用。

在您想要光栅化 DrawingImage 并将其序列化为流的情况下,您是如何发现自己的?如果您需要这样的功能,我觉得您正在以一种不寻常的方式做某事。

不过,您可以通过将 DrawingImage 绘制到 DrawingVisual,将其渲染到 RenderTargetBitmap,然后传递渲染来实现此功能目标到编码器以将栅格数据序列化为流。

public MemoryStream ImageStream(DrawingImage drawingImage)
{
    DrawingVisual visual = new DrawingVisual();
    using (DrawingContext dc = visual.RenderOpen())
    {
        dc.DrawDrawing(drawingImage.Drawing);
        dc.Close();
    }
    RenderTargetBitmap target = new RenderTargetBitmap((int)visual.Drawing.Bounds.Right, (int)visual.Drawing.Bounds.Bottom, 96.0, 96.0, PixelFormats.Pbgra32);
    target.Render(visual);

    MemoryStream stream = new MemoryStream();
    BitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(target));
    encoder.Save(stream);

    return stream;
}

如果您想要更通用的东西,我会把它分成两个方法并更改一些类型。

public BitmapSource Rasterize(Drawing drawing)
{
    DrawingVisual visual = new DrawingVisual();
    using (DrawingContext dc = visual.RenderOpen())
    {
        dc.DrawDrawing(drawing);
        dc.Close();
    }
    RenderTargetBitmap target = new RenderTargetBitmap((int)drawing.Bounds.Right, (int)drawing.Bounds.Bottom, 96.0, 96.0, PixelFormats.Pbgra32);
    target.Render(visual);

    return target;
}

public void SavePng(BitmapSource source, Stream target)
{
    BitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(source));
    encoder.Save(target);
}

然后您可以将它用于任何类型的流。例如,将绘图保存到文件:

using (FileStream file = File.Create("somepath.png"))
{
    SavePng(Rasterize(drawingImage.Drawing), file);
}

关于wpf - 如何将 System.Windows.Media.DrawingImage 转换为 Stream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41916147/

相关文章:

c# - 无法使用样式禁用 WPF 扩展器

c++ - C/C++错误:超出范围读取。寻找错误的内存地址

c# - ASP.NET C#通过FTPwebRequest上传MemoryStream内容问题

c# - 使用布局变换旋转 Canvas

wpf - 如何在 WPF 中创建不可选择的 TreeViewItem

c# - 如何将注意力集中在 WPF 桌面应用程序上?

java - 使用 Canvas 创建 3D 立方体

android - 绘制一个平铺在 Rect android 上的位图

c# - 在 C# .NET 中搜索和替换内存流中的文本

c# - 将 ionic Zip 读取为内存流 C#