Page 1 of 1

Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-21T19:41:03-07:00
by Mgamerz
I'm drawing some bitmaps from a tileset in a game and trying to make some animated GIFs so we don't have to hand-stitch some gifs. I am having an issue where I am getting either some flickering (when optimizing) or some ghosting where previous frames are still shown in further frames. Here are some examples of what I've seen as I try to fool around with it.

Image
Flickering

Image
Ghosting

Image
No Flicker or Ghost but some strange black background on 1 frame, and also not transparent.

I am drawing the images on screen so I am sure the output of my drawing sprite method is OK. Here is my export code - The sprites are drawn on a 256x256 canvas (until the whole sprite is assembled though we wouldn't know the size), and each tile is drawn at a different position in the animation so I can only crop it after I generate all the sprite bitmaps.

Code: Select all

        private void exportedAnimatedGIFOfAnimationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int padding = 2;
            int animationToExport = Convert.ToInt32(animationIndexUpDown.Value);
            Animation anim = ActiveBNSA.Animations[animationToExport];
            using (MagickImageCollection collection = new MagickImageCollection())
            {
                List<GifBitmapDelayPair> sprites = new List<GifBitmapDelayPair>();
                //draw all sprites
                foreach (Frame f in anim.Frames)
                {
                    int animationDelay = Convert.ToInt32(f.FrameDelay * 1.66); //1/60 in ms;
                    sprites.Add(new GifBitmapDelayPair(DrawSprite(f), animationDelay));
                }

                //calculate corners
                int top = 256, left = 256, bottom = 0, right = 0; //inverted maximum values.
                foreach (GifBitmapDelayPair gbdp in sprites)
                {
                    Bitmap b = gbdp.bitmap;
                    var pixelsX = Enumerable.Range(0, b.Width);
                    var pixelsY = Enumerable.Range(0, b.Height);

                    int localleft = pixelsX.FirstOrDefault(
                                x => pixelsY.Any(y => b.GetPixel(x, y).A != 0));
                    int localright = pixelsX.Reverse().FirstOrDefault(
                                x => pixelsY.Any(y => b.GetPixel(x, y).A != 0));
                    int localtop = pixelsY.FirstOrDefault(
                                y => pixelsX.Any(x => b.GetPixel(x, y).A != 0));
                    int localbottom = pixelsY.Reverse().FirstOrDefault(
                                y => pixelsX.Any(x => b.GetPixel(x, y).A != 0));

                    top = Math.Min(top, localtop);
                    left = Math.Min(left, localleft);
                    right = Math.Max(right, localright);
                    bottom = Math.Max(bottom, localbottom);
                }



                //crop bitmaps
                int gifWidth = right - left + padding * 2;
                int gifHeight = bottom - top + padding * 2;
                foreach (GifBitmapDelayPair gbdp in sprites)
                {
                    gbdp.bitmap = CropBitmap(gbdp.bitmap, left - padding, top - padding, gifWidth, gifHeight);
                }

                //add bitmaps to animation
                foreach (GifBitmapDelayPair gbdp in sprites)
                {
                    MagickImage img = new MagickImage(gbdp.bitmap);
                    collection.Last().AnimationDelay = gbdp.delay;
                }


                // Reduce colors (causes flicker)
                //QuantizeSettings settings = new QuantizeSettings();
                //settings.Colors = 256;
                //collection.Quantize(settings);


                // Optionally optimize the images (images should have the same size).
                //collection.Optimize(); //causes ghosting

                //doing neither seems to cause both
                // Save gif
                collection.Write(@"C:\Users\Michael\BNSA\output.gif");
            }
        }
I appreciate your help. I'm not a graphics person really so I don't know if I am missing something crucial.

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-25T12:32:02-07:00
by dlemstra

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-25T22:04:50-07:00
by Mgamerz
Indeed. The option in that UI is under Export > Export Animated GIF. The code is in MainWindow.xaml.cs under Sprite Viewer GUI - WPF.

Here is a BNSA (sprite file) you can load.
https://drive.google.com/open?id=0B9bwv ... XBiWnBaRFE

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-26T01:44:11-07:00
by dlemstra
Thanks. I'll check out your repo and figure out why you are getting these results this weekend.

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-27T06:16:48-07:00
by dlemstra
I cannot export that image as a gif because it crashes inside CalculateAnimationBoundingBox. Can you fix your current master to make sure it can write a gif animation?

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-27T10:47:54-07:00
by Mgamerz
I did not encounter that error in my master from 1 commit ago. However I did fix an issue where the loaded BNSA was overridden with an older load method, which fixes the palette crash.

I have updated the repository.

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-27T13:12:24-07:00
by dlemstra
I have send you a pull request for the fix: https://github.com/RockmanEXEZone/Battl ... ker/pull/1. You needed to change the GifDiposeMethod.

Re: Making gif with transparent backgrounds has ghosting/flickering

Posted: 2017-01-27T17:00:07-07:00
by Mgamerz
Thanks. I knew I was forgetting something...