Contentcontrol + renderStargetBitmap + imagem vazia
-
23-09-2019 - |
Pergunta
Estou tentando criar algumas imagens do gráfico sem nunca exibir esses gráficos na tela. Estou nisso há um bom tempo e tentei muitas coisas diferentes, mas nada parece funcionar. O código funciona perfeitamente se eu exibir o gráfico primeiro em uma janela, mas se eu não exibi -lo em uma janela, o bitmap é apenas branco com uma borda preta (não tenho idéia do porquê).
Tentei adicionar o gráfico a uma fronteira antes de renderizar e dar à fronteira um borderbrush verde. No bitmap, vejo o borderbrush verde e depois o fundo preto e o fundo branco, mas sem gráfico. O gráfico não está contido em um pensionista preto, então não sei de onde isso vem.
Eu tentei adicionar o gráfico a uma janela sem ligar para a janela.Show () e, novamente, apenas pego o pensionista preto e o fundo branco. No entanto, se eu ligar para a janela.Show (), o bitmap contém o gráfico.
Eu tentei usar um drawingvisual como explicado aqui, mesmo resultado.
Aqui está o código (não incluindo a adição do elemento a uma borda ou janela):
private static BitmapSource CreateElementScreenshot(FrameworkElement element, int dpi)
{
if (!element.IsMeasureValid)
{
Size size = new Size(element.Width, element.Height);
element.Measure(size);
element.Arrange(new Rect(size));
}
element.UpdateLayout();
var scale = dpi/96.0;
var renderTargetBitmap = new RenderTargetBitmap
(
(int)(scale * element.RenderSize.Width),(int)(scale * element.RenderSize.Height),dpi,dpi,PixelFormats.Default
);
// this is waiting for dispatcher to perform measure, arrange and render passes
element.Dispatcher.Invoke(((Action)(() => renderTargetBitmap.Render(element))), DispatcherPriority.Render);
return renderTargetBitmap;
}
Nota: O gráfico é um contentControl.
Existe alguma maneira que eu possa fazer com que o gráfico renderize sem exibi -lo em uma janela primeiro?
Solução
Calling element.ApplyTemplate () fez o truque.
Outras dicas
Para mim, Calling Element.arrange () foi a peça que faltava.
Se alguém tem problemas semelhantes com a renderização RenderStargetBitmap (recebendo imagem branca / vazia) itens que estão no Stackpanel você pode movê -los temporários para Rede, então renderize e coloque de volta Stackpanel
Grid grid = new System.Windows.Controls.Grid() { Background = Brushes.White, Width = iWidth, Height = iHeight };
Panel panel = plot.Parent as Panel;
if (panel != null)
{
panel.Children.Remove(plot);
grid.Children.Add(plot);
grid.Measure(new Size(iWidth, iHeight));
grid.Arrange(new Rect(new Size(iWidth, iHeight)));
}
plot.Measure(new Size(iWidth, iHeight));
plot.Arrange(new Rect(new Size(iWidth, iHeight)));
plot.ApplyTemplate();
plot.UpdateLayout();
grid.ApplyTemplate();
grid.UpdateLayout();
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
iWidth,
iHeight,
96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(grid);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
MemoryStream memoryStream = new MemoryStream();
encoder.Save(memoryStream);
bitmap = new System.Drawing.Bitmap(memoryStream);
if (panel != null)
{
grid.Children.Remove(plot);
panel.Children.Add(plot);
}
plot.Measure(new Size(iWidthBefore, iHeightBefore));
plot.Arrange(new Rect(new Size(iWidthBefore, iHeightBefore)));
plot.UpdateLayout();