日期:2014-05-17  浏览次数:21203 次

C# GDI+ 绘图 擦除的问题
现在想画出空心线的效果,目前思路是先画一个粗线,然后将中心范围擦除为与背景色一样的透明色,像下图一样,白色部分是透明色,应该如何处理呢?


------解决方案--------------------
先解释下上面的代码。
上面的代码并非擦除.而是Pen对象的CompoundArray直接封装了绘制多条线条的接口。
上面例子中lines的四个数字分别代表第一条线在宽度上的起始位置、第一条线在宽度上的终止位置、第二条线在宽度上的起始位置、第二条线在宽度上的终止位置。
显然参数1<参数2<参数3<参数4。不恰当的参数数组可能导致错误。
因此,你需要的功能已经实现了。

然后说一下“擦除”。
GDI+的所谓擦除就是用纯色去覆盖。这种纯色显然不包括“透明”的概念。
图形绘制到画布上时,后绘制的图形总是覆盖掉前面绘制的图形。但画布从来就不记录这些,也没有层的概念。
因此,一旦让一个区域“擦除”,就意味着用户需要告诉画布原来下面画的是什么。
所以,不支持层的画布显然不可能直接提供擦除的功能。

如果你真的需要定义擦除,那么需要做很多工作。
0.你要组织层。知道哪些绘图语句是上一层,哪些绘图语句是下一层。
1.将全部绘图的过程(代码)写到画布的Paint事件之中。
2.定一个擦除的矩形区域(一个Rectangle变量)
3.将需要擦除的矩形区域无效。
4.此时,画布会调用Paint时间,并告诉你,哪个矩形无效了。
注意,不仅仅是你引发的擦除会调用Paint事件,窗口被覆盖等原因都会导致Paint事件。
因此,你收到的Paint事件不一定是“擦除”故意引发的事件。
5.在Paint事件里重绘"擦除的层"的全部内容,并绕过你定义的擦除区域。换句话说,重绘所有无效矩形区域内除去你定义的擦除区域所剩下的内容。
显然,这比较难。