Снимок области холста WPF с использованием RenderTargetBitmap
Я хочу создать снимок области холста в моем приложении. Я использую кисть Visual для получения снимка и сохраняю его с помощью PngEncoder. Но полученный PNG - просто пустое черное изображение. Я не уверен, что проблема связана с созданным BitmapSource или с проблемой PNGEncoder. Вот код, который я использую, чтобы получить то же самое.
public void ConvertToBitmapSource(UIElement element)
{
var target = new RenderTargetBitmap((int)(element.RenderSize.Width), (int)(element.RenderSize.Height), 96, 96, PixelFormats.Pbgra32);
var brush = new VisualBrush(element);
var visual = new DrawingVisual();
var drawingContext = visual.RenderOpen();
drawingContext.DrawRectangle(brush, null, new Rect(new Point(0, 0),
new Point(element.RenderSize.Width, element.RenderSize.Height)));
drawingContext.Close();
target.Render(visual);
PngBitmapEncoder encoder = new PngBitmapEncoder();
BitmapFrame outputFrame = BitmapFrame.Create(target);
encoder.Frames.Add(outputFrame);
using (FileStream file = File.OpenWrite("TestImage.png"))
{
encoder.Save(file);
}
}
2 ответа
Не уверен, почему именно ваш код не работает. Это работает:
public void WriteToPng(UIElement element, string filename)
{
var rect = new Rect(element.RenderSize);
var visual = new DrawingVisual();
using (var dc = visual.RenderOpen())
{
dc.DrawRectangle(new VisualBrush(element), null, rect);
}
var bitmap = new RenderTargetBitmap(
(int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default);
bitmap.Render(visual);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using (var file = File.OpenWrite(filename))
{
encoder.Save(file);
}
}
Спасибо вам обоим за вопрос и ответ.
В интересах других, ищущих тот же ответ
Я обнаружил, что путь Клеменса оставляет черную полосу на изображении со смещенным изображением вниз или вправо. Как будто это не рендеринг элемента в правильной позиции в растровом изображении.
Поэтому мне пришлось использовать VisualBrush, как предложил Амар.
Вот код, который работал для меня:
RenderTargetBitmap RenderVisual(UIElement elt)
{
PresentationSource source = PresentationSource.FromVisual(elt);
RenderTargetBitmap rtb = new RenderTargetBitmap((int)elt.RenderSize.Width,
(int)elt.RenderSize.Height, 96, 96, PixelFormats.Default);
VisualBrush sourceBrush = new VisualBrush(elt);
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
using (drawingContext)
{
drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0),
new Point(elt.RenderSize.Width, elt.RenderSize.Height)));
}
rtb.Render(drawingVisual);
return rtb;
}