WPF 如何画出1像素的线

翻译 2017年07月21日 20:30:34

如何有人告诉你,请你画出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

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

相关文章推荐

前端开发——个人作品案例

2014年08月-10月:华思网络仿真云网站; 2014年07月中旬至月底:华侨大学模拟联合国协会MUN网站http://www.wsmun.org/; 2014年07月月初至中旬:个人雅思培训网...

WPF DrawingVisual详解

代码如下:     public partial class MainWindow : Window     {         private DrawingVisual _drawingVisua...

WPF 布局心得 一个像素引发的问题和思考

用xaml布局界面的时候,遇到了这样一个问题。 按钮的白色border边框一边细一边消失了。 正常的情况应该是这样的。 我大致的思路是这样的,可能是外部原因:容纳按钮的容器把按钮的边框挤没了。还...

iOS: 如何正确的绘制1像素的线

一、Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量。系统在实际渲染到设置时会帮助我们处理Point到P...
  • hherima
  • hherima
  • 2015年06月29日 10:30
  • 2320

SA001-借助IBInspectable和约束定制1像素宽的线(view)

在进行产品开发的时候,我们经常遇到UI设计师给出1像素宽的间隔线。而这 种1像素宽的线,通常我们可以拖上一个view,将其宽或者高度设置为1。这在非 Retina屏上是没有问题的:1像素刚好对应的就是...

iOS开发-UI控件:如何画1像素的线

最近在项目中画了一根1像素的线,我是通过直接花一个但是通过PS查看,画了不止1个像素。 原代码语句: ? 1 label1 = [[UILabel alloc] initWithF...

【Java_项目篇<1>】--JAVA实现坦克大战游戏--画出坦克(一)

为什么选择这个项目? 1.好玩,有趣 2.涉及到java基础的各个方面的技术: 面向对象思想、多线程、IO、绘图技术、监听事件、数据库、界面编程 3.巩固旧的知识 黑色框为JFrame 红...

使用TableLayout画出跨行的表格效果,附边框线

由于使用TableLayout画出的表格不知道怎么设置边框线,所以使用一种比较笨的方法。就是用textview作为边框线附在表格上使他看上去像一个表格,话不多说直接看代码。   代码示例:...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WPF 如何画出1像素的线
举报原因:
原因补充:

(最多只允许输入30个字)