.Net 绘图裁剪错误
GDI+ DrawLines 函数有一个剪切错误,可以通过运行以下 c# 代码来重现。 运行代码时,会出现两条线路径,它们应该是相同的,因为它们都在剪切区域内。 但当设置剪切区域时,不会绘制其中一条线段。
protected override void OnPaint(PaintEventArgs e)
{
PointF[] points = new PointF[] { new PointF(73.36f, 196),
new PointF(75.44f, 32),
new PointF(77.52f, 32),
new PointF(79.6f, 196),
new PointF(85.84f, 196) };
Rectangle b = new Rectangle(70, 32, 20, 164);
e.Graphics.SetClip(b);
e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly
e.Graphics.TranslateTransform(80, 0);
e.Graphics.ResetClip();
e.Graphics.DrawLines(Pens.Red, points);
}
在图形对象上设置抗锯齿模式可以解决此问题。 但这不是真正的解决方案。
有人知道解决方法吗?
GDI+ DrawLines function has a clipping bug that can be reproduced by running the following c# code. When running the code, two line paths appear, that should be identical, because both of them are inside the clipping region. But when the clipping region is set, one of the line segment is not drawn.
protected override void OnPaint(PaintEventArgs e)
{
PointF[] points = new PointF[] { new PointF(73.36f, 196),
new PointF(75.44f, 32),
new PointF(77.52f, 32),
new PointF(79.6f, 196),
new PointF(85.84f, 196) };
Rectangle b = new Rectangle(70, 32, 20, 164);
e.Graphics.SetClip(b);
e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly
e.Graphics.TranslateTransform(80, 0);
e.Graphics.ResetClip();
e.Graphics.DrawLines(Pens.Red, points);
}
Setting the antials mode on the graphics object resolves this. But that is not a real solution.
Does anybody know of a workaround?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
代码似乎有什么问题?
好吧,问题应该是……代码应该做什么但它还没有做什么。
当我运行代码时,我看到 2 个红色“尖峰”,我不是故意的吗?
您似乎在剪裁的矩形区域内绘制了第一个尖峰,通过在 Rectangle 声明后添加以下内容进行验证:
e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );
然后您执行平移,重置剪辑,因此此时我假设 clientRectangle 被用作适当的剪辑区域,然后尝试重新绘制平移的尖峰。 哪里有bug?!?
What appears to be the matter with the code?
OK, the question should be... what should the code do that it doesn't already.
When I run the code, I see 2 red 'spikes' am I not meant to?
You appear to draw the first spike within the clipped rectangle region verified by adding the the following after the declaration of the Rectangle :
e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );
Then you perform a translation, reset the clip so at this point I assume the clientRectangle is being used as the appropriate clip region and then attempt to redraw the translated spike. Where's the bug?!?
错误在于,两条线段应该绘制相同,但事实并非如此,因为在剪切区域内绘制的尖峰完全在剪切区域内,并且不应以任何方式进行剪切,但事实确实如此。 这是一个非常烦人的问题,但会导致任何大量使用绘图线+剪切的软件看起来不专业,因为多边形中可能会出现间隙。
The bug is that both line segments should be drawn identical but they are not because the spike that is drawn within the clipping region is completely within the clipping region and should not be clipped in any way but it is. This is a very annoying but that results in any software that uses drawlines heavily + clipping to look unprofessional because of gaps that can appear in the polygons.
看来这是一个已知的错误...
以下代码似乎可以按照您的要求运行:
注意:我已对该行进行了 AntiAlias 处理并将您的剪切区域扩展了 1
看来以下解决方法可能会有所帮助(尽管未经测试) ):
以下是可能/或可能没有帮助的文章列表:
http://www.tech-archive.net/pdf/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0350.pdf" tech-archive.net/pdf/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0350.pdf
http:// www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0368.html
或者...
以下也是可能的:
这有效地使用组合区域进行剪辑/unioned(我认为)与画布/控件的 ClientRectangle 。 由于该区域与矩形不同,因此结果应该是预期的。 添加,可以证明此代码是有效的
通过在 setClip() 调用之后 。 这清楚地显示了仅出现在剪切区域中的黑色矩形。
如果无法选择对线路进行抗锯齿处理,这可能是一个有效的解决方法。
希望这可以帮助
It appears that this is a known bug...
The following code appears to function as you requested:
Note: I have AntiAlias'ed the line and extended your clipping region by 1
it appears that the following work arounds might help (although not tested):
The following is a list of articles that might / or then again might not help:
http://www.tech-archive.net/pdf/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0350.pdf
http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0368.html
OR...
the following is also possible:
This effecivly clips using a region combined/unioned (I think) with the ClientRectangle of the canvas/Control. As the region is difned from the rectangle, the results should be what is expected. This code can be proven to work by adding
after the setClip() call. This clearly shows the black rectangle only appearing in the clipped region.
This could be a valid workaround if Anti-Aliasing the line is not an option.
Hope this helps