winforms - .Net 绘图裁剪错误

标签 winforms graphics gdi+ system.drawing

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);
 }

在图形对象上设置抗锯齿模式可以解决此问题。但这并不是一个真正的解决方案。

有人知道解决方法吗?

最佳答案

看来这是一个已知的错误...

以下代码似乎可以按照您的要求运行:

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) };

        e.Graphics.SmoothingMode =  System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        Rectangle b = new Rectangle(70, 32, 20, 165);
        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);
    }

注意:我对线条进行了 AntiAlias 处理,并将您的剪切区域扩展了 1

看来以下解决方法可能会有所帮助(尽管未经测试):

  • 笔的厚度超过一个像素
  • 线条完全水平或垂直
  • 剪切是针对窗口边界而不是剪切矩形

以下是可能/或者可能没有帮助的文章列表:

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

或者...

以下情况也是可能的:

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 );
        Region reg = new Region( b );
        e.Graphics.SetClip( reg, System.Drawing.Drawing2D.CombineMode.Union);
        e.Graphics.DrawLines( Pens.Red, points ); // clipped incorrectly
        e.Graphics.TranslateTransform( 80, 0 );
        e.Graphics.ResetClip();
        e.Graphics.DrawLines( Pens.Red, points );
    }

这可以有效地使用与 Canvas /控件的 ClientRectangle 组合/联合(我认为)的区域进行剪辑。由于该区域与矩形不同,因此结果应该是预期的。可以通过添加来证明此代码可以工作

e.Graphics.FillRectangle( new SolidBrush( Color.Black ), b );

在 setClip() 调用之后。这清楚地显示了仅出现在剪切区域中的黑色矩形。

如果无法选择对线条进行抗锯齿处理,这可能是一个有效的解决方法。

希望这有帮助

关于winforms - .Net 绘图裁剪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15478/

相关文章:

c# - 使用 ninject 进行 WinForms 对话框的最佳实践是什么?

android 在图片库上写文字

javascript - D3 圆弧的一侧

c# - 在哪里可以找到当前的 Adob​​e 图像格式规范? "Clipping Paths"

c++ - Connect 4 板中的不均匀圆圈

c# - 我怎样才能在 WinForms 应用程序中捕获所有 'unhandled' 异常?

javascript - 如何通过 WinForms 的 WebBrowser 控件处理 Javascript 事件

winforms - 在 winforms 应用程序中调整主窗体大小时如何调整面板大小?

c# - 如何缩放字体以适合指定的矩形

c# - 替换System.Drawing.Point的GetHashCode()方法