【问题标题】:Draw directly to PictureBox直接绘制到 PictureBox
【发布时间】:2015-08-30 18:01:25
【问题描述】:

我正在开发一个屏幕共享应用程序,它不断地循环运行并从套接字接收小帧。下一步是将它们绘制到 PictureBox 中。 当然,我使用线程是因为我不想冻结 ui。

这是我的代码:

 Bitmap frame = byteArrayToImage(buff) as Bitmap;//a praticular bitmap im getting from a socket.
 Bitmap current =  (Bitmap)pictureBox1.Image;
 var graphics = Graphics.FromImage(current);
 graphics.DrawImage(frame, left, top);//left and top are two int variables of course.
 pictureBox1.Image = current;

但现在我收到一个错误:

对象已在别处使用。

在这一行var graphics = Graphics.FromImage(current);

尝试Clone它,创建一个New Bitmap(current)。还是没有成功。

【问题讨论】:

  • 您从图像创建了一个图形上下文,这不再直接引用图片框内的图像,它只是图像的新版本。之后您必须再次将图像设置到图片框中
  • 事实上,您正在操作pictureBox1 持有的图片实例(或者您所说的“直接引用”是什么意思,Icepickle?)。唯一的问题是pictureBox1 根本不知道您对其Image 所做的更改 - 所以它不会重绘自己。尝试致电 pictureBox1.Refresh()pictureBox1.Invalidate()(按照 Icepickle 的建议:pictureBox1.Image = pictureBox1.Image; 应该也可以 - 自己决定)
  • 嗯?...我同意 olydis。只需刷新您的图片框,它就会更新!
  • @Icepickle 看看我的帖子,我编辑了它。感谢您的帮助!
  • @olydis 我只是尝试同时使用它们..它们非常慢。(测量时间)它们减慢了循环执行时间......还有其他建议吗?不过还是谢谢!

标签: c# multithreading picturebox invoke


【解决方案1】:

Invalidate() 你的 PictureBox 让它自己重绘:

Bitmap frame = byteArrayToImage(buff) as Bitmap;
using (var graphics = Graphics.FromImage(pictureBox1.Image))
{
    graphics.DrawImage(frame, left, top);
}
pictureBox1.Invalidate();

如果你需要它是线程安全的,那么:

pictureBox1.Invoke((MethodInvoker)delegate {
    Bitmap frame = byteArrayToImage(buff) as Bitmap;
    using (var graphics = Graphics.FromImage(pictureBox1.Image))
    {
        graphics.DrawImage(frame, left, top);
    }
    pictureBox1.Invalidate();
});

【讨论】:

  • 我刚刚尝试过无效,但它非常非常非常很慢并且使整个绘图过程变慢..请查看我刚刚编辑过的问题中的最后几行。现在我将新图像分配给图片框控件,但我仍然得到一个异常。谢谢!!
  • 请注意在我的示例中如何使用using 块来正确处理图形。这应该可以消除您看到的错误。
  • 请再次查看帖子。刚刚编辑它。谢谢你的一切!
猜你喜欢
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 2011-11-13
  • 2011-09-08
  • 2018-07-06
  • 1970-01-01
  • 2012-01-28
  • 2015-03-14
相关资源
最近更新 更多