Esempio n. 1
0
 /// <summary>
 /// Default constructor.
 /// Sets repeat count to 0 (repeat indefinitely)
 /// Sets colour table strategy to UseGlobal
 /// Sets image quantization quality to 10.
 /// Sets quantizer type to NeuQuant.
 /// Screen size defaults to size of first frame.
 /// </summary>
 public AnimatedGifEncoder()
 {
     _frames            = new Collection <GifFrame>();
     _strategy          = ColourTableStrategy.UseGlobal;
     _quality           = 10;
     _quantizerType     = QuantizerType.NeuQuant;
     _logicalScreenSize = Size.Empty;
     _palette           = new Palette();
 }
Esempio n. 2
0
        /// <summary>
        /// Tests the AnimatedGifEncoder and the encoded GIF file it produces
        /// using the supplied parameters as property values.
        /// </summary>
        private void TestAnimatedGifEncoder(ColourTableStrategy strategy,
                                            int colourQuality,
                                            Size logicalScreenSize)
        {
            _e = new AnimatedGifEncoder();

            // Check default properties set by constructor.
            Assert.AreEqual(ColourTableStrategy.UseGlobal,
                            _e.ColourTableStrategy,
                            "Colour table strategy set by constructor");
            Assert.AreEqual(10,
                            _e.SamplingFactor,
                            "Colour quantization quality set by constructor");
            Assert.AreEqual(Size.Empty,
                            _e.LogicalScreenSize,
                            "Logical screen size set by constructor");

            _e.ColourTableStrategy = strategy;
            _e.SamplingFactor      = colourQuality;
            _e.LogicalScreenSize   = logicalScreenSize;

            // Check property set/gets
            Assert.AreEqual(strategy,
                            _e.ColourTableStrategy,
                            "Colour table strategy property set/get");
            Assert.AreEqual(colourQuality,
                            _e.SamplingFactor,
                            "Colour quantization quality property set/get");
            Assert.AreEqual(logicalScreenSize,
                            _e.LogicalScreenSize,
                            "Logical screen size property get/set");

            foreach (GifFrame thisFrame in _frames)
            {
                _e.AddFrame(thisFrame);
            }

            StackTrace t = new StackTrace();
            StackFrame f = t.GetFrame(1);
            string     fileName
                = "Checks." + this.GetType().Name
                  + "." + f.GetMethod().Name + ".gif";

            _e.WriteToFile(fileName);

            Stream s = File.OpenRead(fileName);

            // global info
            CheckGifHeader(s);
            bool shouldHaveGlobalColourTable
                = (strategy == ColourTableStrategy.UseGlobal);
            LogicalScreenDescriptor lsd
                = CheckLogicalScreenDescriptor(s, shouldHaveGlobalColourTable);

            // Only check the global colour table if there should be one
            ColourTable gct = null;

            if (shouldHaveGlobalColourTable)
            {
                gct = CheckColourTable(s, lsd.GlobalColourTableSize);
            }

            CheckExtensionIntroducer(s);
            CheckAppExtensionLabel(s);
            CheckNetscapeExtension(s, 0);

            CheckFrame(s, gct, Bitmap1());
            CheckFrame(s, gct, Bitmap2());

            // end of image data
            CheckGifTrailer(s);
            CheckEndOfStream(s);
            s.Close();

            // Check the file using the decoder
            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok,
                            _d.ConsolidatedState,
                            "Decoder consolidated state");
            Assert.AreEqual(2, _d.Frames.Count, "Decoder frame count");
            Assert.AreEqual(shouldHaveGlobalColourTable,
                            _d.LogicalScreenDescriptor.HasGlobalColourTable,
                            "Should have global colour table");
            Assert.AreEqual(logicalScreenSize,
                            _d.LogicalScreenDescriptor.LogicalScreenSize,
                            "Decoder logical screen size");

            BitmapAssert.AreEqual(Bitmap1(),
                                  (Bitmap)_d.Frames[0].TheImage,
                                  "frame 0");
            BitmapAssert.AreEqual(Bitmap2(),
                                  (Bitmap)_d.Frames[1].TheImage,
                                  "frame 1");

            bool shouldHaveLocalColourTable = !shouldHaveGlobalColourTable;

            Assert.AreEqual(shouldHaveLocalColourTable,
                            _d.Frames[0].ImageDescriptor.HasLocalColourTable,
                            "Frame 0 has local colour table");
            Assert.AreEqual(shouldHaveLocalColourTable,
                            _d.Frames[1].ImageDescriptor.HasLocalColourTable,
                            "Frame 0 has local colour table");
        }
Esempio n. 3
0
        private void TestUseSuppliedPalette(ColourTableStrategy strategy)
        {
            string globalLocal
                = strategy == ColourTableStrategy.UseGlobal
                                ? "Global"
                                : "Local";

            // First, create and check a series of single-frame GIFs, one for
            // each of the available colour tables.
            string[] files = Directory.GetFiles(@"ColourTables", "*.act");
            foreach (string act in files)
            {
                string actFileWithoutExtension
                    = Path.GetFileNameWithoutExtension(act);
                _e  = new AnimatedGifEncoder();
                if (strategy == ColourTableStrategy.UseGlobal)
                {
                    _e.Palette = Palette.FromFile(act);
                    Assert.AreEqual(ColourTableStrategy.UseGlobal,
                                    _e.ColourTableStrategy);
                    // QuantizerType should default to UseSuppliedPalette when
                    // the encoder's Palette property is set.
                    Assert.AreEqual(QuantizerType.UseSuppliedPalette,
                                    _e.QuantizerType);
                }
                else
                {
                    _e.ColourTableStrategy = ColourTableStrategy.UseLocal;
                    Assert.AreEqual(ColourTableStrategy.UseLocal,
                                    _e.ColourTableStrategy);
                    _e.QuantizerType = QuantizerType.UseSuppliedPalette;
                    Assert.AreEqual(QuantizerType.UseSuppliedPalette,
                                    _e.QuantizerType);
                }

                GifFrame frame
                    = new GifFrame(Image.FromFile(@"images\smiley.bmp"));
                if (strategy == ColourTableStrategy.UseLocal)
                {
                    frame.Palette = Palette.FromFile(act);
                }
                _e.AddFrame(frame);

                string fileName
                    = "AnimatedGifEncoderTest.UseSuppliedPalette"
                      + globalLocal
                      + "-"
                      + actFileWithoutExtension
                      + ".gif";
                _e.WriteToFile(fileName);

                _d = new GifDecoder(fileName, true);
                _d.Decode();

                Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState,
                                actFileWithoutExtension);
                Assert.AreEqual(1, _d.Frames.Count, actFileWithoutExtension);

                if (strategy == ColourTableStrategy.UseGlobal)
                {
                    Assert.AreEqual(true,
                                    _d.LogicalScreenDescriptor.HasGlobalColourTable,
                                    actFileWithoutExtension);
                    Assert.IsNotNull(_d.GlobalColourTable,
                                     actFileWithoutExtension);
                }
                else
                {
                    Assert.AreEqual(false,
                                    _d.LogicalScreenDescriptor.HasGlobalColourTable,
                                    actFileWithoutExtension);
                    Assert.IsNull(_d.GlobalColourTable, actFileWithoutExtension);
                }

                string expectedFileName
                    = @"images\Smiley\Smiley"
                      + "-"
                      + actFileWithoutExtension
                      + ".bmp";
                Image expected = Image.FromFile(expectedFileName);
                ImageAssert.AreEqual(expected, _d.Frames[0].TheImage, expectedFileName);
            }

            // now encode a multi-frame animation with a user-supplied palette
            _d = new GifDecoder(@"images\globe\spinning globe better 200px transparent background.gif");
            _d.Decode();
            _e = new AnimatedGifEncoder();
            _e.QuantizerType = QuantizerType.UseSuppliedPalette;
            _e.Palette       = Palette.FromFile(@"ColourTables\C64.act");
            foreach (GifFrame f in _d.Frames)
            {
                _e.AddFrame(f);
            }
            string globeFileName
                = "AnimatedGifEncoderTest.UseSuppliedPalette"
                  + globalLocal
                  + ".gif";

            _e.WriteToFile(globeFileName);

            _d = new GifDecoder(globeFileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState);
            Assert.AreEqual(_e.Frames.Count, _d.Frames.Count);
        }
Esempio n. 4
0
        public void ExportAnimationAsGif()
        {
            var error = false;

            if (CurrentShownSpriteSheet == null)
            {
                Messager.ShowMessage(Messager.Mode.Exception,
                                     "No spritesheet loaded! Please load a sprite sheet first by clicking the button Import Spritesheet on topbar");
                return;
            }

            if (CurrentShownAnimation != null)
            {
                if (CurrentShownAnimation.Frames.Count == 0)
                {
                    Messager.ShowMessage(Messager.Mode.Exception, "No frames to export. The animation is empty!");
                    return;
                }

                var path = ShowCompleteSaveToDialog("Choose location to save GIF", @"Animated GIF(.gif)|*.gif");

                if (path == null)
                {
                    return;
                }

                if (path.Length == 0)
                {
                    Messager.ShowMessage(Messager.Mode.Exception,
                                         string.Format("Nothing exported. The path is invalid or empty!"));
                    return;
                }

                try
                {
                    Size  frameSize = Size.Empty;
                    Point offSetMin = Point.Empty;
                    Point offSetMax = Point.Empty;

                    foreach (var frame in CurrentShownAnimation.Frames)
                    {
                        if (frame.SpriteFrame.Width > frameSize.Width)
                        {
                            frameSize.Width = frame.SpriteFrame.Width;
                        }
                        if (frame.SpriteFrame.Height > frameSize.Height)
                        {
                            frameSize.Height = frame.SpriteFrame.Height;
                        }
                    }

                    foreach (var frame in CurrentShownAnimation.Frames)
                    {
                        if (frame.OffSetX < offSetMin.X)
                        {
                            offSetMin.X = frame.OffSetX;
                        }
                        if (frame.OffSetY < offSetMin.Y)
                        {
                            offSetMin.Y = frame.OffSetY;
                        }

                        if (frame.OffSetX > offSetMax.X)
                        {
                            offSetMax.X = frame.OffSetX;
                        }
                        if (frame.OffSetY > offSetMax.Y)
                        {
                            offSetMax.Y = frame.OffSetY;
                        }
                    }

                    frameSize.Width += Math.Abs(offSetMin.X) + offSetMax.X;

                    frameSize.Height += Math.Abs(offSetMin.Y) + offSetMax.Y;

                    frameSize.Width = frameSize.Width > frameSize.Height ? frameSize.Width : frameSize.Height;

                    frameSize.Height = frameSize.Width;

                    int repeatCount = CurrentShownAnimation.Loop ? 0 : 1;

                    ColourTableStrategy strategy = ColourTableStrategy.UseGlobal;


                    int quality = 10;

                    AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder
                    {
                        LogicalScreenSize   = frameSize,
                        RepeatCount         = repeatCount,
                        ColourTableStrategy = strategy,
                        SamplingFactor      = quality,
                    };

                    var texture = CurrentShownSpriteSheet.Texture;

                    animatedGifEncoder.Transparent = Color.Black;
                    foreach (var frame in CurrentShownAnimation.Frames)
                    {
                        Bitmap frameBitMap = texture.Surface.ToBitmap(frame.SpriteFrame.Region);

                        GifFrame gifFrame = new GifFrame(frameBitMap);

                        gifFrame.Delay = 100 * ((int)(frame.FrameDuration));

                        if (gifFrame.Delay < 1)
                        {
                            gifFrame.Delay = 1;
                        }

                        gifFrame.Position =
                            new Point((int)((frameSize.Width / 2f - frame.SpriteFrame.Width / 2f) + frame.OffSetX),
                                      (int)((frameSize.Height / 2f - frame.SpriteFrame.Height / 2f) + frame.OffSetY));


                        animatedGifEncoder.AddFrame(gifFrame);
                    }


                    animatedGifEncoder.WriteToFile(path);

                    animatedGifEncoder.Dispose();
                }
                catch (Exception ex)
                {
                    error = true;
                    Messager.ShowMessage(Messager.Mode.Exception,
                                         string.Format("Error on exporting GIF: {0}", ex.Message));
                    Vortex.Debugging.Log.Error(ex, "Error on exporting GIF");
                }
                finally
                {
                    if (!error)
                    {
                        Messager.ShowMessage(Messager.Mode.Message, "GIF created successfully!");
                    }
                }
            }
            else
            {
                Messager.ShowMessage(Messager.Mode.Exception, "No animations to export!");
            }
        }
        /// <summary>
        /// Tests the AnimatedGifEncoder and the encoded GIF file it produces
        /// using the supplied parameters as property values.
        /// </summary>
        private void TestAnimatedGifEncoder( ColourTableStrategy strategy, 
            int colourQuality,
            Size logicalScreenSize)
        {
            _e = new AnimatedGifEncoder();

            // Check default properties set by constructor.
            Assert.AreEqual( ColourTableStrategy.UseGlobal,
                             _e.ColourTableStrategy,
                             "Colour table strategy set by constructor" );
            Assert.AreEqual( 10,
                             _e.SamplingFactor,
                             "Colour quantization quality set by constructor" );
            Assert.AreEqual( Size.Empty,
                             _e.LogicalScreenSize,
                             "Logical screen size set by constructor" );

            _e.ColourTableStrategy = strategy;
            _e.SamplingFactor = colourQuality;
            _e.LogicalScreenSize = logicalScreenSize;

            // Check property set/gets
            Assert.AreEqual( strategy,
                             _e.ColourTableStrategy,
                             "Colour table strategy property set/get" );
            Assert.AreEqual( colourQuality,
                             _e.SamplingFactor,
                             "Colour quantization quality property set/get" );
            Assert.AreEqual( logicalScreenSize,
                             _e.LogicalScreenSize,
                             "Logical screen size property get/set" );

            foreach( GifFrame thisFrame in _frames )
            {
                _e.AddFrame( thisFrame );
            }

            StackTrace t = new StackTrace();
            StackFrame f = t.GetFrame( 1 );
            string fileName
                = "Checks." + this.GetType().Name
                + "." + f.GetMethod().Name + ".gif";
            _e.WriteToFile( fileName );

            Stream s = File.OpenRead( fileName );

            // global info
            CheckGifHeader( s );
            bool shouldHaveGlobalColourTable
                = (strategy == ColourTableStrategy.UseGlobal);
            LogicalScreenDescriptor lsd
                = CheckLogicalScreenDescriptor( s, shouldHaveGlobalColourTable );

            // Only check the global colour table if there should be one
            ColourTable gct = null;
            if( shouldHaveGlobalColourTable )
            {
                gct = CheckColourTable( s, lsd.GlobalColourTableSize );
            }

            CheckExtensionIntroducer( s );
            CheckAppExtensionLabel( s );
            CheckNetscapeExtension( s, 0 );

            CheckFrame( s, gct, Bitmap1() );
            CheckFrame( s, gct, Bitmap2() );

            // end of image data
            CheckGifTrailer( s );
            CheckEndOfStream( s );
            s.Close();

            // Check the file using the decoder
            _d = new GifDecoder( fileName );
            _d.Decode();
            Assert.AreEqual( ErrorState.Ok,
                             _d.ConsolidatedState,
                             "Decoder consolidated state" );
            Assert.AreEqual( 2, _d.Frames.Count, "Decoder frame count" );
            Assert.AreEqual( shouldHaveGlobalColourTable,
                             _d.LogicalScreenDescriptor.HasGlobalColourTable,
                             "Should have global colour table" );
            Assert.AreEqual( logicalScreenSize,
                             _d.LogicalScreenDescriptor.LogicalScreenSize,
                             "Decoder logical screen size" );

            BitmapAssert.AreEqual( Bitmap1(),
                                   (Bitmap) _d.Frames[0].TheImage,
                                   "frame 0" );
            BitmapAssert.AreEqual( Bitmap2(),
                                   (Bitmap) _d.Frames[1].TheImage,
                                   "frame 1" );

            bool shouldHaveLocalColourTable = !shouldHaveGlobalColourTable;
            Assert.AreEqual( shouldHaveLocalColourTable,
                             _d.Frames[0].ImageDescriptor.HasLocalColourTable,
                             "Frame 0 has local colour table" );
            Assert.AreEqual( shouldHaveLocalColourTable,
                             _d.Frames[1].ImageDescriptor.HasLocalColourTable,
                             "Frame 0 has local colour table" );
        }
        private void TestUseSuppliedPalette( ColourTableStrategy strategy )
        {
            string globalLocal
                = strategy == ColourTableStrategy.UseGlobal
                ? "Global"
                : "Local";
            // First, create and check a series of single-frame GIFs, one for
            // each of the available colour tables.
            string[] files = Directory.GetFiles( @"ColourTables", "*.act" );
            foreach( string act in files )
            {
                string actFileWithoutExtension
                    = Path.GetFileNameWithoutExtension( act );
                _e = new AnimatedGifEncoder();
                if( strategy == ColourTableStrategy.UseGlobal )
                {
                    _e.Palette = Palette.FromFile( act );
                    Assert.AreEqual( ColourTableStrategy.UseGlobal,
                                     _e.ColourTableStrategy );
                    // QuantizerType should default to UseSuppliedPalette when
                    // the encoder's Palette property is set.
                    Assert.AreEqual( QuantizerType.UseSuppliedPalette,
                                     _e.QuantizerType );
                }
                else
                {
                    _e.ColourTableStrategy = ColourTableStrategy.UseLocal;
                    Assert.AreEqual( ColourTableStrategy.UseLocal,
                                     _e.ColourTableStrategy );
                    _e.QuantizerType = QuantizerType.UseSuppliedPalette;
                    Assert.AreEqual( QuantizerType.UseSuppliedPalette,
                                     _e.QuantizerType );
                }

                GifFrame frame
                    = new GifFrame( Image.FromFile( @"images\smiley.bmp" ) );
                if( strategy == ColourTableStrategy.UseLocal )
                {
                    frame.Palette = Palette.FromFile( act );
                }
                _e.AddFrame( frame );

                string fileName
                    = "AnimatedGifEncoderTest.UseSuppliedPalette"
                    + globalLocal
                    + "-"
                    + actFileWithoutExtension
                    + ".gif";
                _e.WriteToFile( fileName );

                _d = new GifDecoder( fileName, true );
                _d.Decode();

                Assert.AreEqual( ErrorState.Ok, _d.ConsolidatedState,
                                 actFileWithoutExtension );
                Assert.AreEqual( 1, _d.Frames.Count, actFileWithoutExtension );

                if( strategy == ColourTableStrategy.UseGlobal )
                {
                    Assert.AreEqual( true,
                                     _d.LogicalScreenDescriptor.HasGlobalColourTable,
                                     actFileWithoutExtension );
                    Assert.IsNotNull( _d.GlobalColourTable,
                                      actFileWithoutExtension );
                }
                else
                {
                    Assert.AreEqual( false,
                                     _d.LogicalScreenDescriptor.HasGlobalColourTable,
                                     actFileWithoutExtension );
                    Assert.IsNull( _d.GlobalColourTable, actFileWithoutExtension );
                }

                string expectedFileName
                    = @"images\Smiley\Smiley"
                    + "-"
                    + actFileWithoutExtension
                    + ".bmp";
                Image expected = Image.FromFile( expectedFileName );
                ImageAssert.AreEqual( expected, _d.Frames[0].TheImage, expectedFileName );
            }

            // now encode a multi-frame animation with a user-supplied palette
            _d = new GifDecoder( @"images\globe\spinning globe better 200px transparent background.gif" );
            _d.Decode();
            _e = new AnimatedGifEncoder();
            _e.QuantizerType = QuantizerType.UseSuppliedPalette;
            _e.Palette = Palette.FromFile( @"ColourTables\C64.act" );
            foreach( GifFrame f in _d.Frames )
            {
                _e.AddFrame( f );
            }
            string globeFileName
                = "AnimatedGifEncoderTest.UseSuppliedPalette"
                + globalLocal
                + ".gif";
            _e.WriteToFile( globeFileName );

            _d = new GifDecoder( globeFileName );
            _d.Decode();
            Assert.AreEqual( ErrorState.Ok, _d.ConsolidatedState );
            Assert.AreEqual( _e.Frames.Count, _d.Frames.Count );
        }
Esempio n. 7
0
		/// <summary>
		/// Default constructor.
		/// Sets repeat count to 0 (repeat indefinitely)
		/// Sets colour table strategy to UseGlobal
		/// Sets image quantization quality to 10.
		/// Sets quantizer type to NeuQuant.
		/// Screen size defaults to size of first frame.
		/// </summary>
		public AnimatedGifEncoder()
		{
			_frames = new Collection<GifFrame>();
			_strategy = ColourTableStrategy.UseGlobal;
			_quality = 10;
			_quantizerType = QuantizerType.NeuQuant;
			_logicalScreenSize = Size.Empty;
			_palette = new Palette();
		}