在单独的线程

时间:2016-02-23 12:27:41

标签: c# winforms picturebox

我需要显示一个动画gif,我在PictureBox上从数据库(而不是文件)中检索为BLOB,但是我无法阻止UI。用户可以按下停止引用动画的按钮。

所以我创建了一个包含PictureBox的UserControl,我可以在其中设置要显示的图像。当我在窗体上放置此控件并启动动画时,一切都按预期发生,除了我无法按下按钮,导致窗体被阻止。

当我从一个线程开始动画时,该按钮被启用并可点击,但在这种情况下,动画"闪烁"。

我可以轻松地将PictureBox更改为另一个组件,因为它可以显示GIF动画。如果需要,我也可以将动画gif转换为其他格式......

请注意

  1. 我的图片是来自BLOB的数据库GIF动画而不是普通文件
  2. 我不想(事实上,根据要求它被禁止)用图像创建一个文件(甚至是临时文件)
  3. 有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我的图像是从SQLite数据库中检索出来的,它们存储为BLOB。我的要求禁止创建文件,甚至是临时文件。所以我做的只是在记忆上工作。

此代码获取图像,在帧上对其进行分解,并将PictureBox的图像设置为每帧一次:

   byte[] img = limg.getImage();

   if (img != null)
   {
       MemoryStream ms = new MemoryStream(img);
       newImg = System.Drawing.Image.FromStream(ms);

       GifImage gi = new GifImage(newImg);

       for (int i = 0; i < gi.GetFrameCount; i++)
       {
           this.SetPicture(gi.GetNextFrame(), limg.getWord());
       }
   }

这是将图像设置为PictureBox的代码(注意Sleep,它允许调整动画的速度):

    private void SetPicture(System.Drawing.Image img, string label)
    {
        if (pbOutput.InvokeRequired)
        {
            pbOutput.Invoke(new MethodInvoker(
            delegate()
            {
                pbOutput.Image = img;
                pbOutput.Refresh();
                Thread.Sleep(Interval);
            }));
        }
        else
        {
            pbOutput.Image = img;
            pbOutput.Invalidate();
            Thread.Sleep(Interval);
        }
    }

正如问题所述,问题是由此代码引起的图像闪烁。

解决方案:用函数代码替换 SetPicture 的调用。这样,我就不会调用一个函数,并将它的代码放入&#34; inline&#34;主循环。

不再发生闪烁。