-1

I need to show an animated gif, which I retrieve as a BLOB from a database (rather than a file), on a PictureBox, but I can't block the UI. The user can press a button that stops the referred animation.

So I create a UserControl that contains the PictureBox, where I can set the image to be shown. When I put this control on the form and starts the animation, everything occurs as expected, except for the fact that I can't press the button, 'cause the form is blocked.

When I start the animation from a Thread, the button are enabled and clickable, but in this case the animation "flickers".

I can easily change the PictureBox to another component, since it can show animated gifs. I can also transform the animated gif to some other format, if needed...

Note that

  1. My images are animated gifs that came from BLOB's on a database and not normal files
  2. I do not want (in fact, It's forbidden, by requirements) create a file with the images (even a temporary file)

Any thoughts?

Matt
  • 74,352
  • 26
  • 153
  • 180
Nilo Paim
  • 428
  • 6
  • 22
  • 1
    So you have an animated gif that you have decomposed to frames. You show this frames in the PictureBox and want to allow the user to stop the animation at the current frame at any moment, am I correct? – Eugene Podskal Feb 23 '16 at 12:32
  • 1
    If it is as I have described then you should look into http://stackoverflow.com/questions/10733590/game-development-avoiding-flickers. – Eugene Podskal Feb 23 '16 at 12:35
  • @EugenePodskal You are correct in your description of the situation. I'm already using DoubleBuffered, but the flickering continues. I'll see in depth the link you sent. Thanks a lot. – Nilo Paim Feb 23 '16 at 12:39
  • @EugenePodskal No success at all. None of the sugestions worked. Still searching... :( – Nilo Paim Feb 23 '16 at 13:19
  • Perhaps you should add some code that demonstrates the issue? Also, WinForms are [notoriously bad](http://stackoverflow.com/questions/6391911/c-sharp-winforms-anyone-know-of-a-c-sharp-gdi-library-not-slow-gdi) for any kinds of fast changing graphics. – Eugene Podskal Feb 23 '16 at 13:23
  • @EugenePodskal Question edited. Thanks for your interest. – Nilo Paim Feb 23 '16 at 13:35
  • 1
    Perhaps you can try some manual double buffering or try to increase the interval. Otherwise you will have to use something more performant than WinForms. – Eugene Podskal Feb 23 '16 at 15:30
  • Don't use a different thread. Don't animate the GIF yourself.The `PictureBox` control will display an animated GIF all by itself. All you have to do is set the GIF file directly as the source image for the `PictureBox` using the Winforms Designer. See the marked duplicate for additional details. – Peter Duniho Feb 24 '16 at 02:12
  • 1
    @NiloPaim: I appreciate the effort you are making to make this question relevant for future users. Given how you've explained how your question differs from the duplicate, I have reopened it. Please now add your solution as an answer to your own question, rather than as an addition to your question. You should be able to copy and paste the answer you gave [here](http://stackoverflow.com/revisions/218d0790-0c69-430a-abf2-4aaa232afe13/view-source). – Matt Mar 06 '16 at 11:27

1 Answers1

0

My images are retrieved from a SQLite database, where they are stored as BLOBs. My requirements forbid the creation of files, even temporary ones. So I did it working exclusively on memory.

This code gets the image, decomposes it on frames and sets the image of the PictureBox to be each frame at a time:

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

And this is the code that sets the image to the PictureBox (note the Sleep, that allows adjust the speed of the animation):

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

The problem, as said on the question, is the flickering of the image caused by this code.

The solution: substitutes the call of SetPicture by the code of the function. That way, I don't call a function, and put the code of it "inline" the main loop.

The flickering does not occurs anymore.

Nilo Paim
  • 428
  • 6
  • 22