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

2018-8-10-WPF-如何画出1像素的线的更多相关文章

  1. WPF 如何画出1像素的线

    如何有人告诉你,请你画出1像素的线,是不是觉得很简单,实际上在 WPF 上还是比较难的. 本文告诉大家,如何让画出的线不模糊 画出线的第一个方法,创建一个 Canvas ,添加一个线 界面代码 < ...

  2. IOS上怎样画出1像素的线

    #define SINGLE_LINE_WIDTH (/[UIScreen mainScreen].scale) #define SINGLE_LINE_ADJUST_OFFSET ((/[UIScr ...

  3. WPF在圆上画出刻度线

    思路 我们可以使用Ellipse先画出一个圆当背景,然后用Canvas再叠加画上刻度线,就能得到如下的效果 我们先用Ellipse画一个橙色的圆,然后将Canvas的宽度和高度绑定到Ellipse的宽 ...

  4. java绘图原理------在窗口界面(或面板上)画出一张或多张图片问题解决方法

    /** *@author blovedr * 功能: java绘图原理------在窗口界面(或面板上)画出一张或多张图片问题解决方法 * 日期: 2018年4月28日     16:20 * 注释: ...

  5. 2019-6-27-WPF-如何给定两个点画出一条波浪线

    title author date CreateTime categories WPF 如何给定两个点画出一条波浪线 lindexi 2019-6-27 10:17:6 +0800 2019-6-26 ...

  6. 【IOS开发】如何画1像素的线

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

  7. [WPF] 使用 HandyControl 的 CirclePanel 画出表盘刻度

    1. 前言 最近需要一个 WPF 的表盘控件,之前 Cyril-hcj 写过一篇不错的博客 <WPF在圆上画出刻度线>,里面介绍了一些原理及详细实现的代码: double radius = ...

  8. WPF Blend 脑洞大开的问题:如何用Blend得到或画出一个凹槽、曲面。

    原文:WPF Blend 脑洞大开的问题:如何用Blend得到或画出一个凹槽.曲面. 目标图: 步骤一(放置一个矩形,填充蓝色): 步骤二(复制该矩形,并调整边角,填充粉红色): 第三部:让图形部分重 ...

  9. wpf 在不同DPI下如何在DrawingVisual中画出清晰的图形

    环境Win10 VS2017 .Net Framework4.7.1   本文仅讨论在DrawingVisual中进行的画图.   WPF单位,系统DPI,显示器DPI三者的定义及关系 WPF单位:一 ...

  10. 像画笔一样慢慢画出Path的三种方法(补充第四种)

    今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...

随机推荐

  1. 恶意软件开发(五)Linux shellcoding

    什么是shellcode? Shellcode通常指的是一段用于攻击的机器码(二进制代码),可以被注入到目标计算机中并在其中执行.Shellcode 的目的是利用目标系统的漏洞或弱点,以获取系统控制权 ...

  2. 记录--怎么写一个可以鼠标控制旋转的div?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 说在前面 鼠标控制元素旋转在现在也是一个很常见的功能,让我们从实现div元素的旋转控制开始来了解元素旋转的具体原理和实现方法吧. 效果展示 ...

  3. 记录--Vue中如何导出excel表格

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.导出静态数据 1.安装 vue-json-excel npm i vue-json-excel 注意,此插件对node有版本要求,安装 ...

  4. LOTO示波器参加2023第101届中国(深圳)电子展

    西安乐拓精益信息科技有限公司,专注研发虚拟测量仪器,以虚拟示波器(USB示波器)以及相关衍生产品为主,包括信号发生器,逻辑分析仪等.乐拓科技以研发团队为核心,着力开发高性价比的示波器产品.无论您是资深 ...

  5. top 命令解释

    PID:进程ID USER:运行改进程的用户 PR:进程的优先级 NI:Nice值,进程的优先级修正值,负值表示高优先级,正值表示低优先级 VIRT:虚拟内存,进程使用的虚拟内存总量 RES:物理内存 ...

  6. C# OpenCvSharp MatchTemplate 多目标匹配

    效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.D ...

  7. 正则表达式 vs. 字符串处理:解析优势与劣势

    1. 正则表达式起源与演变 正则表达式(Regular Expression)最早由美国数学家斯蒂芬·科尔内基(Stephen Kleene)于1956年提出,用于描述字符串的模式匹配规则.随后在计算 ...

  8. verilog之wire和reg

    verilog之wire和reg 1.区别 wire为线,reg为寄存器.至少初期这两个名词的意思是这样的.wire在电路设计中指代的就是某个点的逻辑值,而reg则指代某个寄存器输出的逻辑值.这个理解 ...

  9. YOLOv1/v2/v3简述 | 目标检测

    YOLO系列是目标检测领域里十分经典的结构,虽然目前已经出了很多更高质量更复杂的网络,但YOLO的结构依然可以给算法工程师们带来很多的启发.这3篇论文看下来,感觉像是一本调参说明书,教你如何使用各种t ...

  10. 一个可以让你有更多时间摸鱼的WPF控件(一)

    前言 我们平时在开发软件的过程中,有这样一类比较常见的功能,它没什么技术含量,开发起来也没有什么成就感,但是你又不得不花大量的时间来处理它,它就是对数据的增删改查.当我们每增加一个需求就需要对应若干个 ...