c#在另一个上绘制位图

时间:2016-07-06 07:58:59

标签: c# multithreading sockets bitmap

我正在开发一个项目,我需要绘制一个图像块(作为位图),我从一个已经存在的图像(我在程序的开始中定义)的套接字中接收它,并显示它在PictureBox上 - 换句话说,每当我收到一个新的块时更新图像。

为了异步执行此操作,我使用Thread来读取Socket中的数据并对其进行处理。

这是我的代码:

private void MainScreenThread() {

ReadData();
initial = bufferToJpeg(); //full screen first shot.
pictureBox1.Image = initial;

while (true) {
 int pos = ReadData();
 int x = BlockX();
 int y = BlockY();
 Bitmap block = bufferToJpeg(); //retrieveing the new block.

 Graphics g = Graphics.FromImage(initial);
 g.DrawImage(block, x, y); //drawing the new block over the inital image.
 this.Invoke(new Action(() => pictureBox1.Refresh())); //refreshing the picturebox-will update the intial;

 }
}
  private Bitmap bufferToJpeg()
    {
      return (Bitmap)Image.FromStream(ms);        
    }

我收到错误

  

对象目前正在其他地方使用

Graphics创建行

Graphics g = Graphics.FromImage(initial);

我没有使用任何其他线程或访问位图的东西..所以我不确定这里有什么问题..

如果有人能够启发我,我会非常感激。

感谢。

2 个答案:

答案 0 :(得分:1)

尝试在循环之前分配图形:

private void MainScreenThread() {

  ReadData();
  initial = bufferToJpeg(); 
  pictureBox1.Image = initial;
  Graphics g = Graphics.FromImage(initial);

  while (true) {
    int pos = ReadData();
    int x = BlockX();
    int y = BlockY();
    Bitmap block = bufferToJpeg(); 

    g.DrawImage(block, x, y); 
    this.Invoke(new Action(() => pictureBox1.Refresh())); 

  }
}

答案 1 :(得分:-1)

因为你在使用图形对象之后就永远不会处理它。

如果查看图形组件,则在创建它时。你使用"初始"位图。图形现在指向这个"初始"对象,第一次它将成功创建图形,但第二次(因为' g'尚未处置/已被释放)" initial"在创建新图形之前,旧图形仍在使用对象。

你能做的是:

private void MainScreenThread() {

   ReadData();
   initial = bufferToJpeg(); //full screen first shot.
   pictureBox1.Image = initial;

   while (true) {
    int pos = ReadData();
    int x = BlockX();
    int y = BlockY();
    Bitmap block = bufferToJpeg(); //retrieveing the new block.

    using(Graphics g = Graphics.FromImage(initial)) {
       g.DrawImage(block, x, y); //drawing the new block over the inital image.
       this.Invoke(new Action(() => pictureBox1.Refresh())); //refreshing the picturebox-will update the intial;
   }
 }
}

将会发生的事情是''对象将在使用后处理,以便您可以在之后再次执行相同的操作。

修改:修复 - 未正确将整个代码包含为代码块。