title author date CreateTime categories
WPF 解决 ViewBox 不显示线的问题
lindexi
2018-11-21 09:37:53 +0800
2018-2-13 17:23:3 +0800
WPF

ViewBox 是一个好用的东西,但是在他缩小的时候,可能有一些线无法显示。
现在公司项目就是做一个类似 ppt 的软件,所以需要使用缩略图,而对于矩形形状,在缩略图,经常看不到线。
因为 ViewBox 和 visualBrush 都使用 邻近算法 所以 ViewBox 和 visualBrush 都存在丢失线的问题。
本文提供一个算法,解决 单线条在WPF不显示问题。1像素线段在WPF不显示问题。ViewBox 缩小失去线段问题。

我发现这个问题,于是在 堆栈网提问:https://stackoverflow.com/q/44495238/6116637,最后在walterlv 的帮助下,找到解决方法。

先来说下问题:

如果使用 ViewBox 缩小一个矩形,如果线段只有 1 像素,那么容易就丢失。

请看上图,左边就是一个矩形,右边是使用 ViewBox 做出来的缩小图形。可以看到存在线条不显示,但是在移动矩形过程中,有些线就显示了,于是看起来图形在闪烁,这个设计不好。

当然为了显示矩形,我需要使用 VisualBrush 。为了说明 ViewBox 问题,我用了两个方法,一个就是使用 一个ViewBox 里面放矩形。一个就是使用 ViusalBrush 显示矩形。得到结果差不多, ViewBox 和 visualBrush 都会丢失线段。

         <Border x:Name="SlideBorder" Margin="10,10,10,100" BorderThickness="1" BorderBrush="White">
<Border.Background>
<VisualBrush Visual="{Binding ElementName=Rectangle}" Stretch="Uniform" />
</Border.Background>
</Border>
            <Viewbox  >
<Grid x:Name="Rectangle" Background="#FFFFFFFF">
<Rectangle Margin="10,50,10,10" Stroke="#FF565656"
StrokeThickness="1"
UseLayoutRounding="True"> </Rectangle>
</Grid> </Viewbox>

但是大家都知道,ps 缩小图片,不会容易就出现线段不显示,于是能否使用和 ps 相似的方法?

答案,是的。于是使用的技术有:控件截图、改变图片大小

通过控件截图得到控件的图片,然后通过改变图片大小方式,不会让线段不显示。

wpf 截图

可以使用下面代码截图,width 是图片像素宽度,height是高度

             var bitmap = new RenderTargetBitmap(width, height, 96.0 dpi 就是96, 96.0, PixelFormats.Pbgra32);
bitmap.Render(控件);

如果dpi不是96,那么请使用其他值

通过上面方法就可以截图,然后需要修改图片大小。

修改图片大小

修改图片大小,可以使用TransformedBitmap

如果需要把图片修改为大小为 size ,请使用下面代码,这个代码的效率很高。

    new TransformedBitmap(bitmap, new ScaleTransform(size.Width / 图片宽度, size.Height / 图片高度))

这样可以返回一个 BitmapImage ,于是就得到从输入一个控件到输出一个图片

通过上面的方法,可以使用和 VisualBrush 的方法,把控件转为图片,但是效率没有 visualBrush 那么高。不过在 1280*720P 的控件效率大概比 VisualBrush 时间大概多不到 50 毫秒。当然我的配置比较高也有关,TransformedBitmap 的代码是在 GPU 计算的,而截图是在 UI 线程,所以需要注意一下。

总的代码就是:

        public static BitmapSource ToBitmapSource(Visual visual, Size size)
{
var bounds = VisualTreeHelper.GetDescendantBounds(visual);
var width = (int) Math.Round(bounds.Width);
var height = (int) Math.Round(bounds.Height);
var bitmap = new RenderTargetBitmap(width, height, 96.0, 96.0, PixelFormats.Pbgra32);
bitmap.Render(visual);
return new TransformedBitmap(bitmap, new ScaleTransform(size.Width / width, size.Height / height));
}

输入你需要转换的控件,输入转换后的大小,得到一个图片

于是大概就是 VisualBrush 的功能。

于是使用上面的代码,尝试缩小,可以看到不会丢失线

缺点:无法获得用户的输入,得到是图片,只能用于显示

大法的缩略图,是在用户输入完成在做新的图片,尝试移动一个图片,在移动中,缩略图是不显示的。

呆磨:http://download.csdn.net/detail/lindexi_gd/9868941

参见:How to fix VisualBrush lost line?

how to avoid a single pixel line disappear in wpf?

2018-11-21-WPF-解决-ViewBox--不显示线的问题的更多相关文章

  1. China Intelligent Office Summit(2018.11.21)

    时间:2018.11.21地点:中关村软件园国际会议中心

  2. 2018.11.21 struts2获得servletAPI方式及如何获得参数

    访问servletAPI方式 第一种:通过ActionContext (重点及常用 都是获得原生对象) 原理 Action配置 被引入的配置文件 在页面调用取值 第二种:通过ServletAction ...

  3. 打印出1,11,21,31,41。。。。。。的shell脚本

    打印出1,11,21,31,41......的shell脚本 方法一:#!/bin/bash ;i<;i=i+));do echo $i #cat -n /etc/services | sed ...

  4. Microsoft Artificial Intelligence Conference(2018.05.21)

    时间:2018.05.21地点:北京嘉丽大酒店

  5. OI生涯回忆录 2018.11.12~2019.4.15

    上一篇:OI生涯回忆录 2017.9.10~2018.11.11 一次逆风而行的成功,是什么都无法代替的 ………… 历经艰难 我还在走着 一 NOIP之后,全机房开始了省选知识的自学. 动态DP,LC ...

  6. International Programming Retreat Day(2018.11.17)

    时间:2018.11.17地点:北京国华投资大厦

  7. Intel Artificial Intelligence Conference(2018.11.14)

    时间:2018.11.14地点:北京国贸大酒店

  8. WPF解决界面全屏化但不遮挡任务栏的问题

    原文:WPF解决界面全屏化但不遮挡任务栏的问题 学习C#有一段时间了,现在跟着做项目,碰到有个客户端界面总是全屏,对于客户来说没有任务栏很不习惯,所以做了些略微的修改   </pre>&l ...

  9. WPF解决按钮上被透明控件遮盖时无法点击问题

    原文:WPF解决按钮上被透明控件遮盖时无法点击问题 IsHitTestVisible="False" 在控件上设置如上属性即可,即可让透明控件不触发点击效果

  10. 第33次Scrum会议(11/21)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/21 11:35~11:57,总计22min.地点:东北 ...

随机推荐

  1. vue 编写插件

    1.    将插件逻辑封装成一个对象  最后在install编写业务代码暴露给Vue对象 好处: 可以添加任意参数在这个对象上 方便将install函数封装的更加精简 可拓展性也比较高 2.  将所有 ...

  2. 原 jeecms9自定义标签以及使用新创建的数据库表

    转载地址:https://blog.csdn.net/nice_meng/article/details/89179089 本系统使用的是jeecmsv9版本,收集网上知识后,进行个人汇总 首先,自己 ...

  3. Hibernate命名策略

    hibernate的命名策略,可以减少对数据库标识符命名的维护,进一步减少这部份命名的重复性代码量,以提高维护. hibernate的命名方式,有两类,一类是显式命名,一类是隐式命名. 显式命名:在映 ...

  4. 新闻内页 上一篇写一篇问题,ID不连续,不用链表

    y要什么链表? 用sql查询上一篇 SELECT id,title FROM t_article WHERE id<10 ORDER BY id DESC LIMIT 1; 用sql查下一篇 S ...

  5. day65-test

    目录 一.点击事件控制标签颜色 二.实现点击次数,变换页面标签的颜色 三.周期性实现颜色的旋转变色 练习题 一.点击事件控制标签颜色 1.有 红.黄.蓝 三个按钮,以及一个200x200矩形框box, ...

  6. redis键(key)

    redis键: 用于管理redis的键 command key_name > set runoodkey redis OK > del runoodkey 上面的例子中,del是一个命令, ...

  7. SpringBoot防XSS攻击

    1 . pom中增加依赖 <!-- xss过滤组件 --> <dependency> <groupId>org.jsoup</groupId> < ...

  8. mac mamp host 配置

    <VirtualHost *:80> DocumentRoot "/Users/xuxu/www" ServerName localhost <Directory ...

  9. 通过ajax从jsp页面传输数据到web层,并从web层返回数据给jsp页面

    jsp中ajax代码: 1 $.ajax({ var id = $("#studentid").val();//获取标签中的学生id url:'${pageContext.requ ...

  10. oracle使用dblink跨库查询的例子

    本文介绍了oracle数据库使用dblink进行跨库查询的方法,oracle dblink跨库查询教程,需要的朋友参考下.   oracle dblink跨库查询 方法一:首先,创建数据库链接: 复制 ...