3

对不起,我的英语不好。

我想将 DrawingVisual 渲染为位图,以便创建 DiffuseMaterial。我这样做:

public DiffuseMaterial GetDiffuseMaterial(string text, string font, double fontSize, Brush brush)
{
    FormattedText formattedText = new FormattedText(text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface(font), fontSize, brush);
    DrawingVisual drawingVisual = new DrawingVisual();
    using (DrawingContext drawingContext = drawingVisual.RenderOpen())
        drawingContext.DrawText(formattedText, new Point(0, 0));

    RenderTargetBitmap bmp = new RenderTargetBitmap((int)(text.Length * fontSize), (int)fontSize, 96, 96, PixelFormats.Pbgra32);
    bmp.Render(drawingVisual);

    DiffuseMaterial mat = new DiffuseMaterial(new ImageBrush(bmp));
    mat.Freeze();
    return mat;
}

但...

  • 如果我使用 GetDiffuseMaterial 方法 10000 次,应用程序就会停止。这是“正常的”,因为每个应用程序最多可以有10000 个 GDI 句柄,而 RenderTargetBitmap 每次创建时使用 1 个 GDI 句柄。
  • 解决此问题的方法是释放 RenderTargetBitmap 对象。但我没来得及做。我试过这个(在 mat.Freeze() 和 return mat; 之间):

           bmp.Freeze();  
           bmp = null;  
           GC.Collect();  
           GC.WaitForPendingFinalizers();  
           GC.Collect();  
    
  • 另一种方法是只有一个 RenderTargetBitmap 并将其作为参数提供给 GetDiffuseMaterial。
    但是如果我调用两次 GetDiffuseMaterial,我将有两个相同的材质,因为句柄是共享的,材质采用最后修改。(所以即使文本参数不一样!)

我看不到用 RenderTargetBitmap 做我想做的另一种方法。
注意:GetDiffuseMaterial 可以调用 100 万次...

RenderTargetBitmap 是我发现从字符串文本创建 DiffuseMaterial 的最快方法。其他技术真的很慢:使用带有 TextBlock 的 VisualBrush,使用 DrawingBrush,... 例如:使用 RenderTargetBitmap 对 GetDiffuseMaterial 的 5000 次调用至少比其他技术快 10 倍。

谢谢您的帮助。

4

0 回答 0