WPF 如何画出1像素的线
如何有人告诉你,请你画出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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
WPF 如何画出1像素的线的更多相关文章
- IOS上怎样画出1像素的线
#define SINGLE_LINE_WIDTH (/[UIScreen mainScreen].scale) #define SINGLE_LINE_ADJUST_OFFSET ((/[UIScr ...
- WPF在圆上画出刻度线
思路 我们可以使用Ellipse先画出一个圆当背景,然后用Canvas再叠加画上刻度线,就能得到如下的效果 我们先用Ellipse画一个橙色的圆,然后将Canvas的宽度和高度绑定到Ellipse的宽 ...
- 【IOS开发】如何画1像素的线
最近在项目中画了一根1像素的线,我是通过直接花一个但是通过PS查看,画了不止1个像素. 原代码语句: label1 = [[UILabel alloc] initWithFrame:CGRectMak ...
- iOS: 如何正确的绘制1像素的线
iOS 绘制1像素的线 一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮 ...
- iOS 绘制1像素的线
一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到P ...
- 2019-6-27-WPF-如何给定两个点画出一条波浪线
title author date CreateTime categories WPF 如何给定两个点画出一条波浪线 lindexi 2019-6-27 10:17:6 +0800 2019-6-26 ...
- [示例] Firemonkey 画出 1 点像素的线
说明:在 Firemonkey 在移动平台 Android & iOS 要直接在 Canvas 画出 1 点像素的线,似乎有点困难,不过利用一点小技巧,还是能达到这个要求的,首先要建立一个 B ...
- wpf 在不同DPI下如何在DrawingVisual中画出清晰的图形
环境Win10 VS2017 .Net Framework4.7.1 本文仅讨论在DrawingVisual中进行的画图. WPF单位,系统DPI,显示器DPI三者的定义及关系 WPF单位:一 ...
- [WPF] 使用 HandyControl 的 CirclePanel 画出表盘刻度
1. 前言 最近需要一个 WPF 的表盘控件,之前 Cyril-hcj 写过一篇不错的博客 <WPF在圆上画出刻度线>,里面介绍了一些原理及详细实现的代码: double radius = ...
随机推荐
- 201521123101 《Java程序设计》第1周学习总结
1. 本周学习总结 在学习Java之前要做好准备工作,了解Java从研发后开始如何一步步完善,其与C++.C语言的异同,然后下载JDK.Eclipse.Notepad等软件,以便于未来的学习. 2. ...
- Java、javax、org、sun、Java.util等常用包的区别、详解、实例
Java.javax.org.sun包都是jdk提供的类包,且都是在rt.jar中.rt.jar是JAVA基础类库(java核心框架中很重要的包),包含lang在内的大部分功能,而且rt.jar默认就 ...
- Ring3层 UNICODE_STRING
今天写驱动用到UNICODE_STRING,就在Ring3层抠了一些源代码,学习一下,不多说了上代码了 #pragma once #include <windows.h> #include ...
- Shiro第五篇【授权过滤、注解、JSP标签方式、与ehcache整合】
授权过滤器测试 我们的授权过滤器使用的是permissionsAuthorizationFilter来进行拦截.我们可以在application-shiro中配置filter规则 <!--商品查 ...
- webservice第二篇【自定义webservice服务、soa、uddi概念、soap协议】
自定义webservice服务 我们在上一章节中已经使用wsimport生成本地代理来调用webservice的服务了,其实我们自己写的web应用程序也是可以发布webservice的 我们发布了we ...
- [10] 过滤器 Filter
1.过滤器的基本概念和作用 在网站的页面访问时,我们往往需要做一些控制,如普通用户无法访问VIP用户的页面.如果在每一个需要访问控制的文件中都加上判断代码,那么代码将会很冗余,一旦需要统一修改时也极其 ...
- Struts2第二篇【开发步骤、执行流程、struts.xml讲解、defalut-struts讲解】
前言 我们现在学习的是Struts2,其实Struts1和Struts2在技术上是没有很大的关联的.Struts2其实基于Web Work框架的,只不过它的推广没有Struts1好,因此就拿着Stru ...
- Oracle SQL*Plus 数据备份为 sql 文件
在某些比较严格的环境中,不提供像PL/SQL Developer 这样的工具供我们备份表数据时,使用SQL*Plus运行如下脚本内容导出数据. 1, 执行时登录SQL*Plus, 命令 @D: ...
- spark、storm与Hadoop
1. Storm是什么,怎么做,如何做的更好?Storm是一个开源的分布式实时计算系统,它可以简单.可靠地处理大量的数据流.Storm有很多应用场景,如实时分析.在线机器学习.持续计算.分布式RPC. ...
- Android 8.0 功能和 API
Android 8.0 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 用户体验 通知 在 Android 8.0 中,我们已重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的 ...