【问题标题】:Graphics.DrawImage Doesn't Always Paint The Whole Bitmap?Graphics.DrawImage 并不总是绘制整个位图?
【发布时间】:2009-11-29 00:45:40
【问题描述】:

我在使用Graphics.DrawImage 时遇到了一个奇怪的问题。

当在OnPaint 中使用e.Graphics.DrawImage(Image, Point) 在控件上绘制位图“缓冲区”时,似乎省略了部分图像。缓冲区填充在一个辅助方法中,该方法使用从它构造的Graphics 直接绘制到Bitmap 上。当控件绘制时,缓存的位图会绘制在控件上。

位图本身似乎没有任何遗漏,因为当我将位图保存到光盘并检查时,它就在那里。 (见下图)

这是位图缓冲区的样子:

(来源:zachjohnson.net

这是控件上显示的内容:

(来源:zachjohnson.net

这就是我在OnPaint所做的一切:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    if (this.bufferInvalid)
    {
        this.UpdateBuffer();
    }

    if (this.buffer != null)
    {
        e.Graphics.DrawImage(this.buffer, Point.Empty);
    }
}

【问题讨论】:

  • 省略了哪些部分?你从哪里得到位图?你做什么来触发 Paint 事件?
  • 我编辑了我的问题并添加了更多细节,包括图片。

标签: .net winforms gdi+ drawing bitmap


【解决方案1】:

当调用 OnPaint 时,Windows 有一个允许绘画进入的无效区域,并且其他所有内容都被剪裁。当您想要更新矩形控件时,您应该在 Windows API 中调用 InvalidateRect 以确保整个矩形是无效区域的一部分。只要控件的任何部分无效,就会自动调用 OnPaint。

【讨论】:

  • 谢谢!我需要做的就是调用Control.Refresh()(这会使整个控件无效并重绘)。
  • Control.Invalidate() 几乎总是比 Control.Refresh() 好。
【解决方案2】:

您可以尝试几种不同的方法。

  • 将代码发布到“UpdateBuffer”
  • 在 updatebuffer 调用之后执行 bitmap.save(即 buffer.save)并检查位图的样子。
  • 确保首先绘制了所有控件,并且没有控件被绘制为透明等。
  • 把“onpaint”和“update buffer”的代码放到单独的项目中测试,看看是否有效。
  • 取出“base.onpaint”并检查会发生什么
  • 尝试调用 bitmap.drawimageunscaled 而不是 bitmap.drawimage
  • 尝试使用 new point(0,0) 代替 point.empty(很长一段时间,但你永远不知道...)

大量的调试选项,只需缩小范围即可。

【讨论】:

    【解决方案3】:

    查看System.Windows.Forms.ControlStyles.ResizeRedraw

    【讨论】:

      猜你喜欢
      • 2013-05-05
      • 2013-03-08
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多