在单独线程的 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 转换为其他格式...
请注意
- 我的图像是来自数据库中的 BLOB 而不是普通文件的 gif 动画
- 我不想(事实上,这是被要求禁止的)用图像创建一个文件(即使是一个临时文件)
有什么想法吗?
我的图像是从 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" 放在主循环中。
不再出现闪烁。
我需要在 PictureBox 上显示动画 gif,我从数据库(而不是文件)中将其作为 BLOB 检索,但我无法阻止 UI。用户可以按下停止引用动画的按钮。
所以我创建了一个包含 PictureBox 的 UserControl,我可以在其中设置要显示的图像。当我将此控件放在窗体上并启动动画时,一切都按预期进行,除了我无法按下按钮,因为窗体被阻止。
当我从线程启动动画时,按钮已启用且可单击,但在这种情况下动画 "flickers"。
我可以轻松地将 PictureBox 更改为另一个组件,因为它可以显示动画 gif。如果需要,我还可以将动画 gif 转换为其他格式...
请注意
- 我的图像是来自数据库中的 BLOB 而不是普通文件的 gif 动画
- 我不想(事实上,这是被要求禁止的)用图像创建一个文件(即使是一个临时文件)
有什么想法吗?
我的图像是从 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" 放在主循环中。
不再出现闪烁。