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

时间:2017-01-28 23:45:26

标签: 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后,位图始终为null。任何消化如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

您的bitmap变量始终为空的原因是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);
}