将DrawingImage转换为BitmapImage

时间:2013-01-17 20:14:11

标签: c# wpf bitmapimage

我想绘制大量的形状(线条,椭圆和......),然后将它们保存为位图或png。我制作了图纸,问题是:如何在C#中将 DrawingImage 转换为 BitmapImage ?代码是这样的:

DrawingGroup drawingGroup = new DrawingGroup();
using(DrawingContext context = drawingGroup.Open())
{
    //make some drawing 
}
DrawingImage drawingImage = new DrawingImage(drawingGroup)

// your suggestion? DrawingImage - > BitmapImage

2 个答案:

答案 0 :(得分:6)

您可以将ImageDrawing放入Image控件并将其呈现为RenderTargetBitmap,这是一个BitmapSource,因此可以通过BitmapEncoder(本例中为PngBitmapEncoder)进行序列化。

public void SaveDrawingToFile(Drawing drawing, string fileName, double scale)
{
    var drawingImage = new Image { Source = new DrawingImage(drawing) };
    var width = drawing.Bounds.Width * scale;
    var height = drawing.Bounds.Height * scale;
    drawingImage.Arrange(new Rect(0, 0, width, height));

    var bitmap = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
    bitmap.Render(drawingImage);

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

    using (var stream = new FileStream(fileName, FileMode.Create))
    {
        encoder.Save(stream);
    }
}

请注意,实际上并不需要BitmapImage进行编码,因为BitmapSource(或RenderTargetBitmap等任何派生类)将被接受为BitmapFrame.Create的参数。


稍微不同的解决方案将涉及DrawingVisual而不是DrawingImage:

public void SaveDrawingToFile(Drawing drawing, string fileName, double scale)
{
    var drawingVisual = new DrawingVisual();

    using (var drawingContext = drawingVisual.RenderOpen())
    {
        drawingContext.PushTransform(new ScaleTransform(scale, scale));
        drawingContext.PushTransform(new TranslateTransform(-drawing.Bounds.X, -drawing.Bounds.Y));
        drawingContext.DrawDrawing(drawing);
    }

    var width = drawing.Bounds.Width * scale;
    var height = drawing.Bounds.Height * scale;
    var bitmap = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
    bitmap.Render(drawingVisual);

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

    using (var stream = new FileStream(fileName, FileMode.Create))
    {
        encoder.Save(stream);
    }
}

答案 1 :(得分:0)

我发现这样很简单:

public static BitmapSource ToBitmapSource(DrawingImage source)
{
    DrawingVisual drawingVisual = new DrawingVisual();
    DrawingContext drawingContext = drawingVisual.RenderOpen();
    drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(source.Width, source.Height)));
    drawingContext.Close();

    RenderTargetBitmap bmp = new RenderTargetBitmap((int)source.Width, (int)source.Height, 96, 96, PixelFormats.Pbgra32);
    bmp.Render(drawingVisual);
    return bmp;
}

您可以使用它来获取System.Drawing.Bitmap

using (MemoryStream ms = new MemoryStream())
{
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(ToBitmapSource(drawingImage)));
    encoder.Save(ms);

    using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms))
    {
        bmpOut = new System.Drawing.Bitmap(bmp);
    }
}