zoukankan      html  css  js  c++  java
  • 2018-8-10-WPF-如何画出1像素的线

    title author date CreateTime categories
    WPF 如何画出1像素的线
    lindexi
    2018-08-10 19:16:53 +0800
    2018-2-13 17:23:3 +0800
    WPF

    如何有人告诉你,请你画出1像素的线,是不是觉得很简单,实际上在 WPF 上还是比较难的。 本文告诉大家,如何让画出的线不模糊

    画出线的第一个方法,创建一个 Canvas ,添加一个线

    界面代码

                <Canvas x:Name="Canvas"></Canvas>
    

    在后台添加一条线

                Line myLine = new Line();
    
                myLine.Stroke = System.Windows.Media.Brushes.Black;
    
                myLine.X1 = 100;
                myLine.X2 = 200;  // 150 too far
                myLine.Y1 = 200;
                myLine.Y2 = 200;
    
                myLine.StrokeThickness = 1;
    
                Canvas.Children.Add(myLine);

    那么如何看到线模糊呢?

    简单方法是使用 ViewBox 和放大镜,可以看到模糊

    在界面添加下面代码

        <Viewbox >
                <Canvas x:Name="Canvas"></Canvas>
        </Viewbox>

    这时拖动窗口可以看到线放大

    可以看到线是模糊的,如果想要让线不模糊,可以添加下面的代码

            myLine.SnapsToDevicePixels = true;
                myLine.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);

    这个方法是从 [https://stackoverflow.com/q/2879033/6116637][https://stackoverflow.com/q/2879033/6116637]得到,但是无法对于自己的控件

    如果自己创建一个控件,那么直接使用 dc.DrawLine 得到不是清晰的

    创建一个类自定义控件,添加下面的代码画出线

            protected override void OnRender(DrawingContext dc)
            {
               
                    dc.DrawLine(_pen,  new Point(10, 10), new Point(310, 10));
                
            }

    可以看到,画出来的线是模糊的,于是看了微软的代码

    看了他的矩形是如何画的,看到他画出来的是清晰的,但是复制他的代码到我的控件,画出来不是清晰的

            /// <summary>
            /// Render callback.
            /// </summary>
            protected override void OnRender(DrawingContext drawingContext)
            {
                Pen pen = GetPen();
                drawingContext.DrawRoundedRectangle(Fill, pen, _rect, RadiusX, RadiusY);
            }

    下面代码是我复制他的,但是自己的控件画出来在放大时,线模糊,所以直接复制是无法做到wr的矩形那样

           protected override void OnRender(DrawingContext dc)
            {
    
                dc.DrawRoundedRectangle(null, _pen, new Rect(new Point(10, 10), new Size(100, 100)), 5, 5);
            }

    在界面画出来wr 的矩形和自定义控件,可以看到,微软的是清晰的

    那么是不是wr 做了特殊的东西,到现在还不知道,但是找到了一个方法,可以画出清晰

    缩小看到的图片是这样

    那么放大时就是下面这张图

    所以需要在放大时,也画一个像素, 这个方法就是本文,所以这是在翻译,只是没有使用对所有的文字翻译,来自工藤大神的方法。

    本文使用的方法很简单,第一步

    复制方法到一个静态类

        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();
        }

    然后就可以在自定义控件使用下面的代码

          protected override void OnRender(DrawingContext dc)
            {
                dc.DrawSnappedLinesBetweenPoints(_pen,1, new[]
                {
                    new Point(10, 10),
                    new Point(310, 10),
                });
            }

    可以看到线是清晰的

    参见:https://stackoverflow.com/a/45189552/6116637

    http://www.nbdtech.com/Blog/archive/2008/11/20/blurred-images-in-wpf.aspx

  • 相关阅读:
    js组件之间的通信
    localStorage, localforage, web sql三者的比较
    最近的学习计划
    无状态的web应用
    转 :meta name的含义:<META http-equiv=Content-Type content="text/html; charset=gb2312">
    css清除浮动的方法汇总
    segfault at 7fff6d99febc ip 0000003688644323 sp 00007fff6d99fd30 error 7 in libc.so.6[3688600000+175000]
    Linux内核定时器
    TCPIP网络协议层对应的RFC文档
    UIDocumentPickerViewController使用
  • 原文地址:https://www.cnblogs.com/lindexi/p/12086241.html
Copyright © 2011-2022 走看看