【问题标题】:WPF DrawingContext seems ignore SnapToDevicePixelsWPF DrawingContext 似乎忽略了 SnapToDevicePixels
【发布时间】:2011-08-26 11:05:48
【问题描述】:

我正在通过在DrawingContext 上直接调用DrawLine 来绘制图表。由于我想避免任何抗锯齿功能,我尝试将 SnapToDevicePixels=true 放在父 UIElement 上,但我仍然有抗锯齿:

该项目是不是为 WPF4 编写的旧操作系统项目,但我将其重新定位到 Framework4,这也可能是一个问题吗?

【问题讨论】:

    标签: wpf graphics antialiasing


    【解决方案1】:

    GuidelineSet 旨在解决您的问题。

    @Marat Khasanov 推荐你使用GuidelineSet,你回答说它弄乱了你的代码。我也被这个问题困扰,所以我写了下面的代码,用不丑的代码来解决这个问题。

    注意:此方法即使在Viewbox 中也有效。

    public static class SnapDrawingExtensions
    {
        public static void DrawSnappedLinesBetweenPoints(this DrawingContext dc,
            Pen pen, double lineThickness, params Point[] points)
        {
            var guidelineSet = new GuidelineSet();
            foreach (var point in points)
            {
                guidelineSet.GuidelinesX.Add(point.X);
                guidelineSet.GuidelinesY.Add(point.Y);
            }
            var half = lineThickness / 2;
            points = points.Select(p => new Point(p.X + half, p.Y + half)).ToArray();
            dc.PushGuidelineSet(guidelineSet);
            for (var i = 0; i < points.Length - 1; i = i + 2)
            {
                dc.DrawLine(pen, points[i], points[i + 1]);
            }
            dc.Pop();
        }
    }
    

    调用OnRender中的方法并传递线点给它。

    protected override void OnRender(DrawingContext dc)
    {
        // Draw four horizontal lines and one vertical line.
        // Notice that even the point X or Y is not an integer, the line is still snapped to device.
        dc.DrawSnappedLinesBetweenPoints(_pen, LineThickness,
            new Point(0, 0), new Point(320, 0),
            new Point(0, 40), new Point(320, 40),
            new Point(0, 80.5), new Point(320, 80.5),
            new Point(0, 119.7777), new Point(320, 119.7777),
            new Point(0, 0), new Point(0, 120));
    }
    

    这是视图框中的渲染结果:

    【讨论】:

      【解决方案2】:

      我找到了this link,他们基本上说你应该设置

      ParentUIElement.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
      

      它对我有用,所以值得一试!

      【讨论】:

        【解决方案3】:

        SnapsToDevicePixels 仅适用于元素边界框。您需要将 Guidelines 与 DrawingContext 一起使用。如果符合您的要求,您也可以指定VisualXSnappingGuidelinesVisualYSnappingGuidelines

        【讨论】:

        • 您的建议确实有效。为了生成正确的指南,我必须考虑我将绘制的所有坐标,甚至添加一半的笔宽。这会生成一个非常混乱的代码(写这样的东西是一场噩梦)难道没有一些捷径吗?
        • @Felice Pollano:我什么也没找到 :( 甚至框架类都使用原始解决方案“new GuidelineSet -> GuidelineSet.Add -> PushGuidelineSet”。例如,看看 TickBar 类的 OnRender 方法。
        • 感谢您的回复。其实我正在看结果,不知道它是否具有抗锯齿效果......
        猜你喜欢
        • 2021-10-28
        • 2016-09-30
        • 2016-03-16
        • 2014-02-03
        • 2012-03-11
        • 2013-09-07
        • 2016-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多