当前位置:C++技术网 > 精选软件 > GDI渐变:2 原因分析和验证:斜向颜色渐变的黑线黑点问题

GDI渐变:2 原因分析和验证:斜向颜色渐变的黑线黑点问题

更新时间:2016-11-05 00:42:23浏览次数:1+次

    在文章《斜向颜色渐变的黑线黑点问题探究分析和解决方案》中,我们已经知道了斜向颜色渐变的黑线黑点问题的探索过程和解决办法。然而,问题到底是什么呢?我们现在还是不知道。

    要不要找到问题的根本,是一个分水岭。只停留于解决问题,而对问题的根本不闻不问,过着得过且过的日子,技术思想难有长进,也就只能不停的搬砖,没有自己的技术底蕴。而在解决问题的基础上,应对了工作的要求,又把空余时间拿来探究里面的奥秘,不仅让技术开发变得更加有意思,而且可以不断的开拓自己的视野,提高自己的技术底蕴。不多说,你懂的。就看你怎么选择,不要用累作为借口。都深夜十二点了,我还在写总结,而不是自己研究一下就完了。你还有什么好说的呢?

    下面是60度角的时候的效果图:

原因分析和验证:斜向颜色渐变的黑线黑点问题

    虽然通过大量的验证,我们增加线条的宽度解决了黑点黑线问题,然而,问题如何出现的,却是毫不知情。为了知其然知其所以然,就需要深入的探究一下了。

    要明白黑点黑线从哪来,那就要仔细的看看黑点黑线的规律了。其实从哪些图片都看不出什么直接的规律。那么我们放大图片来仔细看看那些细小的点是什么样呢?在探寻这个原因之前,我没有任何把握能够找到问题。但是,不管结果如何,先做再说。

    整体上看不到效果,那么我们放大看看。你可以用图片查看器来放大,也可以用画图板来放大,不过推荐用画图板来放大,这个更加专业。不信,可以看看效果图:

图片查看器放大到最大的效果

【图片查看器放大到最大的效果】

画图板放到最大的效果

【画图板放到最大的效果】

    而且图片查看器缩小图片看到的效果也不满意:

图片查看器缩小图片看到的效果也不满意

    千万不要觉得以上这个细节不重要,这个对我们的观察影响很大。在左上角的位置,几乎是白色的,图片查看器显示了阴影,会干扰判断。而画图板看上去非常清晰。

    当然,画图板看上去的黑点,其实也没有看出什么名堂。你期望从这些黑点中找到什么规律吗?反正我没有报希望。

    背景色是白色的,所以我们看不到背景的纹路,也就不知道黑点处于什么位置。我们需要网格那样的东西。这样可以确切的知道每一个点的位置和关系。如果是白板,没有参考,没有研究价值。

    那么网格从哪来呢?要什么样的网格呢?

    因为我们这里有画斜线,自然不能画水平和垂直的网格。那真的就成了研究坐标位置了。没有太大的意义。我们要研究的是,这些点所处的位置有我们奥秘。我们千万不要去寻找这些点的位置坐标的数学规律,那是作死。反正我数学不够厉害,我做不到。

    我们这里是画斜线形成斜向渐变,然后出现了黑点。那么网格应该是由斜线构成的,而不是水平或者垂直的线构成的。所以,我在渐变色的基础上,每隔几根线画一根黑线。并没有发现什么。如果每一根黑线都画出来,那全部都是黑色的了。包括我们要研究的黑线在内。不管怎么样,用黑线去研究黑点,当黑线和黑点碰到一块,谁能分得清楚呢?

    但是又迫切需要网格线来定位黑点。我们这里是彩色图,很自然就想到了用红绿蓝三色的斜线来间隔绘制。不同的线不会连成一片,而且和黑点区别开了。这样可以形成背景网格,来定位黑点。而实现连续的三色的斜线的代码,就不在这里贴了,局部代码也没有意义,因为和上下文有关。何况我们要聚焦在寻找这个问题上。

    下面是画了三色背景网格线的画面:

画了三色背景网格线的画面

    这画面,看的眼花缭乱。三色独立划线,而不是之前的彩色了,所以画面看起来有点让人不安。不过,请仔细看。图中依然可以看到黑色的点的分布。然后还可以看到斜向的线条痕迹。整体这样看,还是看不出什么。

    那么请用画图板,来放大这个眼花缭乱的图吧。效果如下:

三色斜线背景色

    这是在画图板放大了前面一张图的一部分的效果,这个稍微比前面一张图好点,看的清楚一些。黑色的点似乎被嵌入在网格之中了。从整体来看,就是我们渐变色看到的黑点的分布,位置是一样的。那么我们再仔细看看每一个黑点的位置有什么内在秘密。

    我们在这个图可以看到,我们在没有放大之前看到的线可能感觉挺直的。然后在放大到最大后,看到的三色的直线,其实并不直。斜线由长短不一的像素连接成斜线。整个斜线为了保持斜线的角度一致,才使用了长短不一的像素块连接成一条斜线。这个是GDI内部实现的。这样的线条也是会出现锯齿的。GDI为了效率,所以没有做过多的计算,只是大致算了一下,然后就这样绘制了一条斜线。因为像素很小,所以有时候肉眼看不太清楚锯齿,不过还是可以看得出来。

    看到这里,我希望你能够明白GDI为什么斜线有锯齿,GDI的斜线是如何组成的,这个图很直观的表现出来了。当然,这个不是我们这里的主题。我们继续分析黑点的来源。

    我们到了这一步,基本只需要细心的观察和分析,就可以找到原因了。我们仔细观察每一个线的连接规律,然后会发现,三色线在连接的时候,因为线宽为1,在斜线与斜线之间,没有完全贴合,形成了空隙。而这个空隙也就是线条没有画到的地方。

    而当我们改变角度的时候,实际在改变斜线的斜率,不同的斜率会导致相邻的斜线的贴合度不一样,角度小的时候,贴合度较好。水平线条完全平行贴合,没有任何缝隙。当然,垂直的时候,也是。然后角度较小时,贴合度好,看不到黑点。而当角度不断的变大,斜率不断的变大,贴合度越来越不好,才让有些地方空出来了,就出现了黑点。在60度附近的范围,贴合度非常差。也就是说,贴合度是非标准正态分布的(不知道这个叫法对不对,装逼一下,哈哈哈)。左边少到没有朋友,中间最集中,右边慢慢变少。

    那么将线条宽度设置大于1为什么会让黑点消失呢?当线条宽度大于1的时候,我的坐标计算还是按照1像素的单位在递进,这样也就表示,后一条斜线,会覆盖前一条斜线的后面一部分,这样会导致线条组成的画面会覆盖所有的空间,也就不会出现黑点了。而黑点被后一条的线条颜色给替代。这样一点,局部的这些黑点被线条颜色替代,不就是渐变色的一种嘛。所以,就和原有的渐变色融为一体,不分你我了。看到的就是整体漂亮的渐变色。而实际上,内部的斜线线条还是有锯齿的。

   为了验证双线条确实是后一条覆盖前一条,可以设置线条宽度为2,看图:

双线条确实是后一条覆盖前一条

【线宽为2的相互叠加的效果】

    可以看到,最终的效果还是单线条,但是却很好的覆盖了所有的空间。我们再来看线条宽度为3的效果:

线条宽度为3的效果

    和线条宽度为2的基本一样,也是单斜线。我们不能让线条刚好的平行贴合,需要重叠的连续,否则斜线因为锯齿形状,会导致空隙的产生。

    再说说黑色从哪来的?我用的是内存DC来一次性画好,然后贴图,加速绘制效率。而内存DC用的背景色是黑色。所以空隙的位置自然就是黑色的了。

    那么到此,所有问题就真的找到,并分析验证通过了。