形状与DrawingVisual的表现

时间:2013-09-09 09:26:55

标签: c# wpf performance shapes drawingvisual

MSDN写道:

  

DrawingVisual是一个轻量级绘图类,用于渲染形状,图像或文本。此类被视为轻量级,因为它不提供布局,输入,焦点或事件处理,提高其性能。因此,图纸非常适合背景和剪贴画。

我编写了一个代码,通过Line对象绘制了数千行,并通过DrawingVisual对象在图像上绘制了数千行。比较两种方式的表现我没有看到差异。在任何一种情况下,滚动最终图片都不够顺利。

为什么每种情况下滚动的延迟都相同,而且DrawingVisual的性能优势在哪里?

第一种方式

<ScrollViewer HorizontalScrollBarVisibility="Auto" 
              VerticalScrollBarVisibility="Auto">
    <Canvas Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
            Name="layoutView">
        <Image>
            <Image.Source>
                <DrawingImage>
                    <DrawingImage.Drawing>
                            <ImageDrawing x:Name="testImage"/>
                    </DrawingImage.Drawing>
                </DrawingImage>
            </Image.Source>
        </Image>
    </Canvas>
</ScrollViewer>

ImageSource imageSource = new BitmapImage(uri);

testImage.Rect = new Rect(
    0, 0, imageSource.Width, imageSource.Height);
testImage.ImageSource = imageSource;

layoutView.Width = imageSource.Width;
layoutView.Height = imageSource.Height;

Random r = new Random();

int max = Math.Min(
    (int)imageSource.Height, (int)imageSource.Width);

for (int i = 0; i < 1000; i++)
{
    Point p1 = new Point(r.Next(max), r.Next(max));
    Point p2 = new Point(r.Next(max), r.Next(max));

    Line line = new Line();
    line.X1 = p1.X;
    line.Y1 = p1.Y;
    line.X2 = p2.X;
    line.Y2 = p2.Y;
    line.Stroke = Brushes.Red;

    layoutView.Children.Add(line);
}

第二种方式

<ScrollViewer HorizontalScrollBarVisibility="Auto" 
              VerticalScrollBarVisibility="Auto">
    <my:VisualView Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
                   x:Name="layoutView">
    </my:VisualView>
</ScrollViewer>

public class VisualView : Canvas
{
    List<Visual> visuals = new List<Visual>();

    protected override int VisualChildrenCount
    {
        get
        {
            return visuals.Count;
        }
    }

    protected override Visual GetVisualChild(int index)
    {
        return visuals[index];
    }

    public void AddVisual(Visual visual)
    {
        visuals.Add(visual);
        base.AddVisualChild(visual);
        base.AddLogicalChild(visual);
    }

    public void RemoveVisual(Visual visual)
    {
        visuals.Remove(visual);
        base.RemoveVisualChild(visual);
        base.RemoveLogicalChild(visual);
    }
}

ImageSource imageSource = new BitmapImage(uri);

Random r = new Random();

int max = Math.Min(
    (int)imageSource.Height, (int)imageSource.Width);

DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
    dc.DrawImage(imageSource, new Rect(
        0, 0, imageSource.Width, imageSource.Height));
    dc.Close();

    layoutView.AddVisual(dv);

    layoutView.Width = imageSource.Width;
    layoutView.Height = imageSource.Height;
}

Pen pen = new Pen(Brushes.Red, 1);
for (int i = 0; i < 1000; i++)
{
    dv = new DrawingVisual();
    using (DrawingContext dc = dv.RenderOpen())
    {
        Point p1 = new Point(r.Next(max), r.Next(max));
        Point p2 = new Point(r.Next(max), r.Next(max));

        dc.DrawLine(pen, p1, p2);
        dc.Close();

        layoutView.AddVisual(dv);
    }
}

1 个答案:

答案 0 :(得分:1)

您需要仔细衡量才能看到真正的差异。可能有一些WPF ETW事件可以提供帮助。

如果你是这样,你有图像和矢量图形。如果图像在这里占主导地位,那么任何一种方式都可能非常相似。

首先尝试删除图像以查看是否有差异。

使用矢量时,不应创建1000个DrawingVisual,可以在单个Visual中绘制1000行。您甚至可以绘制一条折线。

使用单个折线,您可以通过删除不影响线条形状的点来进一步优化。

相关问题