LinearGradientBrush 神器解决方法?
.net 中的 LinearGradientBrush(甚至是整个 GDI+ 中的?)似乎有一个严重的错误:有时,它会引入伪影。 (请参阅此处< /a> 或此处 - 本质上,线性渐变的第一条线是在最终颜色中绘制的,即从白色到黑色的渐变将从黑色线开始,然后使用适当的白色到黑色渐变)
我想知道是否有人找到了解决此问题的方法? 这是一个非常烦人的 bug :-(
这是 Artifacts 的图片,请注意有 2 个 LinearGradientBrush:
替代文本http://img142.imageshack.us/img142/7711/gradientartifactmm6.jpg
The LinearGradientBrush in .net (or even in GDI+ as a whole?) seems to have a severe bug: Sometimes, it introduces artifacts. (See here or here - essentially, the first line of a linear gradient is drawn in the endcolor, i.e. a gradient from White to Black will start with a Black line and then with the proper White to Black gradient)
I wonder if anyone found a working workaround for this? This is a really annoying bug :-(
Here is a picture of the Artifacts, note that there are 2 LinearGradientBrushes:
alt text http://img142.imageshack.us/img142/7711/gradientartifactmm6.jpg
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我在使用渐变画笔时也注意到了这一点。 我唯一有效的解决方法是始终创建所有边缘比要使用它绘制的区域大 1 像素的渐变画笔矩形。 这可以保护您免受所有四个边缘的问题的影响。 缺点是边缘使用的颜色与您指定的颜色相差一小部分,但这比绘图伪像问题要好!
I have noticed this as well when using gradient brushes. The only effective workaround I have is to always create the gradient brush rectangle 1 pixel bigger on all edges than the area that is going to be painted with it. That protects you against the issue on all four edges. The downside is that the colors used at the edges are a fraction off those you specify, but this is better than the drawing artifact problem!
您可以在矩形上使用很好的 Inflate(int i) 方法来获得更大的版本。
You can use the nice Inflate(int i) method on a rectangle to get the bigger version.
我会巧妙地处理菲尔上面的回答(这确实是一条评论,但我没有这个特权)。 我看到的行为与文档相反,其中表示:
也就是说,在某些情况下您会得到单个像素环绕。 据我所知(通过实验),只有当矩形的宽度或高度为奇数时,我才会遇到问题。 因此,为了解决该错误,我发现当且仅当尺寸(扩展前)为奇数时,将 LinearGradientBrush 矩形增加 1 像素就足够了。 换句话说,始终将画笔矩形的宽度和高度向上舍入到下一个偶数个像素。
因此,为了填充矩形
r
,我使用类似:Insane but true。
I would finesse Phil's answer above (this is really a comment but I don't have that privilege). The behaviour I see is contrary to the documentation, which says:
Namely you get a single pixel wrap-around in some cases. As far as I can tell (by experimentation) I only get the problem when the width or height of the rectangle is odd. So to work around the bug I find it is adequate to increase the LinearGradientBrush rectangle by 1 pixel if and only if the dimension (before expansion) is an odd number. In other words, always round the brush rectangle up the the next even number of pixels in both width and height.
So to fill a rectangle
r
I use something like:Insane but true.
至少对于 WPF,您可以尝试使用
GradientStop
在边缘处获得 100% 正确的颜色,即使是在过度绘制时也是如此。At least with WPF you could try to use
GradientStop
s to get 100% correct colors right at the edges, even when overpainting.我在 C++ 代码中也经历过伪影。 解决问题的方法是为 Graphics 对象设置非默认的 SmoothingMode。 请注意,所有非默认平滑模式都使用坐标系,该坐标系绑定到像素的中心。 因此,您必须正确地将矩形从 GDI 坐标转换为 GDI+ 坐标:
看起来 LinearGradientBrush 仅在高质量模式下才能正常工作。
I experienced artifacts too in my C++ code. What solved the problem is setting a non-default SmoothingMode for the Graphics object. Please note that all non-default smoothing modes use coordinate system, which is bound to the center of a pixel. Thus, you have to correctly convert your rectangle from GDI to GDI+ coordinates:
It seems like LinearGradientBrush works correctly only in high-quality modes.