Как мне преобразовать 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;
}