Как мне преобразовать DrawingVisual в растровое изображение?

Используя Visual C# 2010, я пытаюсь записать файл.avi из кадров, полученных из Windows Kinect. Кадры могут быть сохранены достаточно легко как файлы.png с использованием BitmapEncoder и PngBitmapEncoder (сохранение в поток), но я не могу добавить эти изображения по своему усмотрению в VideoStream, предоставленный здесь: http://www.codeproject.com/Articles/7388/A-Simple-C-Wrapper-for-the-AviFile-Library потому что мне нужно иметь возможность преобразовать либо RenderTargetBitmap, либо DrawingVisual в System.Drawing.Bitmap.

Я нашел примеры кодов, которые делают похожие вещи, но все они, кажется, хотят создать экземпляр класса Image, который, как говорит мне Visual Studio, является абстрактным и не может быть создан.

Я хожу по кругу и никуда не денусь.

Я просто хочу сделать что-то вроде этого:

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

Но у Bitmap нет никаких полезных конструкторов, чтобы перенести меня из dv (DrawingVisual) в bmp.:(

Эти 3 строки взяты из этого фрагмента:

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);

1 ответ

Результатом использования RenderTargetBitMap является BitFapSource WPF, который не конвертирует сам Visual в BitmapSource, он содержит результат преобразования в виде BitmapSource, Для того, чтобы преобразовать BitmapSource к System.Drawing.Bitmap попробуйте использовать измененную версию кода из этого сообщения на форуме MSDN.

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);  
}

Создан метод для возврата вашего растрового изображения

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 bitmapSource = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96, 96, PixelFormats.Pbgra32);
            var drawingVisual = new DrawingVisual();
            using (var drawingContext = drawingVisual.RenderOpen())
            {
                var visualBrush = new VisualBrush(visual);
                drawingContext.DrawRectangle(transparentBackground, null, new Rect(new Point(), bounds.Size));
                drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), 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;
        }
Другие вопросы по тегам