简体   繁体   English

C#在另一张图上绘制位图

[英]c# Drawing bitmap over another one

I'm working on a project,and i need to draw blocks of images(as bitmaps) which i receive from a socket on an already existing image (which i define in the beggining of the program),and to display it on a PictureBox -in other words,to update the image everytime i receive a new block. 我正在一个项目上,我需要在一个已经存在的图像(我在程序的开头定义)中绘制从套接字接收的图像块(作为位图),并将其显示在PictureBox -换句话说,每次我收到一个新块时都要更新图像。

In order to do this asynchronously, i use a Thread which read the data from the Socket and process it. 为了异步执行此操作,我使用了一个Thread ,该ThreadSocket读取数据并进行处理。

This is my code: 这是我的代码:

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

I'm getting an error 我遇到错误

object is currently in use elsewhere 该对象当前在其他地方使用

On the Graphics creation line Graphics创建行上

Graphics g = Graphics.FromImage(initial);

I'm not using any other threads or somthing ot access the bitmap..so i'm not sure what's the problem here.. 我没有使用任何其他线程或其他东西来访问位图..所以我不确定这是什么问题。

If anyone can enlighten me i'll be really thankful. 如果有人能启发我,我将非常感激。

Thanks. 谢谢。

Try to assign the graphics before the loop: 尝试在循环之前分配图形:

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

  }
}

Its because you never dispose the graphics object after its being used. 这是因为您永远不会在使用图形对象后对其进行处置。

If you look at the graphics component, when you create it. 如果您查看图形组件,则在创建时。 You use the "initial" bitmap. 您使用“初始”位图。 The graphics are now pointing at this "initial" object, first time it will succeed to create the graphics but second time (since the 'g' has not been disposed/been released) the "initial" object is still being in use by the old graphics before creating a new one. 图形现在指向该“初始”对象,第一次它将成功创建图形,但是第二次(由于尚未释放/释放“ g”),“初始”对象仍在使用中。旧图形,然后再创建新图形。

What you can do is: 您可以做的是:

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

What will happen is that the 'g' object will be disposed after being used so that you can do the same operation again afterwards. 将会发生的情况是'g'对象在使用后将被处置,以便您以后可以再次执行相同的操作。

Edit : Fix- Didnt properly include the whole code as a code block. 编辑 :修复-正确地将整个代码作为代码块包括在内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM