在单独线程的 PictureBox 中显示动画 gif(作为 BLOB 检索)

Show an animated gif (retrieved as a BLOB) in a PictureBox on a separate thread

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

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

当我从线程启动动画时,按钮已启用且可单击,但在这种情况下动画 "flickers"。

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

请注意

  1. 我的图像是来自数据库中的 BLOB 而不是普通文件的 gif 动画
  2. 我不想(事实上,这是被要求禁止的)用图像创建一个文件(即使是一个临时文件)

有什么想法吗?

我的图像是从 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 的代码(注意睡眠,它允许调整动画速度):

    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的调用替换为函数代码。这样,我就不会调用函数,而是将它的代码 "inline" 放在主循环中。

不再出现闪烁。