简体   繁体   中英

How do I convert DrawingVisual to a Bitmap?

Using Visual C# 2010, I'm trying to write an .avi file from frames received from a Windows Kinect. The frames can be saved easily enough as .png files with the use of a BitmapEncoder and PngBitmapEncoder (saving to a stream) but I can't add these images at my discretion to a VideoStream provided here: http://www.codeproject.com/Articles/7388/A-Simple-C-Wrapper-for-the-AviFile-Library because I need to be able to convert either a RenderTargetBitmap or a DrawingVisual to a System.Drawing.Bitmap.

I've found example codes that do similar things but they all seem to want to instantiate the Image class which Visual Studio tells me is abstract and can't be instantiated.

I'm going round in circles and not getting anywhere.

I just want to do something like this:

...
renderBitmap.Render(dv);
Bitmap bmp=new Bitmap(dv);
VideoStream aviStream=aviManager.AddVideoStream(true,60,bmp);
...

But Bitmap has no useful constructors to get me from dv (DrawingVisual) to bmp. :(

Those 3 lines come from this snippet:

var renderBitmap=new RenderTargetBitmap(colorWidth,colorHeight,96.0,96.0,PixelFormats.Pbgra32);
DrawingVisual dv=new DrawingVisual();
using(DrawingContext dc=dv.RenderOpen())
{
    VisualBrush backdropBrush=new VisualBrush(Backdrop);
    dc.DrawRectangle(backdropBrush,null,new Rect(0,0,colorWidth,colorHeight));
    VisualBrush colorBrush=new VisualBrush(MaskedColor);
    dc.DrawRectangle(colorBrush,null,new Rect(0,0,colorWidth,colorHeight));
    VisualBrush watermarkBrush=new VisualBrush(Watermark);
    dc.DrawRectangle(watermarkBrush,null,new Rect(colorWidth-96,colorHeight-80,64,48));
}
renderBitmap.Render(dv);
Bitmap bmp=new Bitmap(dv);
VideoStream aviStream=aviManager.AddVideoStream(true,60,bmp);

The result of using RenderTargetBitMap is a WPF BitMapSource it doesn't convert the Visual itself to a BitmapSource , it contains the result of the conversion as a BitmapSource . In order to convert a BitmapSource to a System.Drawing.Bitmap try using a modified version of the code from this MSDN Forum Post .

renderBitmap.Render(dv);
BitmapSource bmp = renderBitmap;

using(MemoryStream outStream = new MemoryStream())
{
    BitmapEncoder enc = new BmpBitmapEncoder();
    enc.Frames.Add(BitmapFrame.Create(bmp));
    enc.Save(outStream);
    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
    VideoStream aviStream=aviManager.AddVideoStream(true,60,bitmap);  
}

Created a Method to return your Bitmap

renderBitmap.Render(dv);
BitmapSource bmp =renderBitmap;

VideoStream aviStream = aviManager.AddVideoStream(true, 60, ConvertToBitmap(bmp));

private System.Drawing.Bitmap ConvertToBitmap(BitmapSource target)
{
    System.Drawing.Bitmap bitmap;

    using (MemoryStream outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(target));
        enc.Save(outStream);
        bitmap = new System.Drawing.Bitmap(outStream);
    }

    return bitmap;
}
private BitmapSource ToBitmapSource(Visual visual, Brush transparentBackground)
{
    var bounds = VisualTreeHelper.GetDescendantBounds(visual);
    var scale = VisualTreeHelper.GetDpi(visual);
    var bitmapSource = new RenderTargetBitmap(
        (int)(bounds.Width * scale.DpiScaleX),
        (int)(bounds.Height * scale.DpiScaleY),
        scale.PixelsPerInchX,
        scale.PixelsPerInchY,
        PixelFormats.Pbgra32);
    var drawingVisual = new DrawingVisual();
    using (var drawingContext = drawingVisual.RenderOpen())
    {
        drawingContext.DrawRectangle(transparentBackground, null, new Rect(bounds.Size));
        drawingContext.DrawRectangle(new VisualBrush(visual), null, new Rect(bounds.Size));
    }
    bitmapSource.Render(drawingVisual);
    return bitmapSource;
}

private System.Drawing.Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
    System.Drawing.Bitmap bitmap;
    using (MemoryStream outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapsource));
        enc.Save(outStream);
        bitmap = new System.Drawing.Bitmap(outStream);
    }
    return bitmap;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM