示例#1
0
        public void BadEncodingUsingGameboyPaletteLocal()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();
            _e.ColourTableStrategy = ColourTableStrategy.UseLocal;
            _e.QuantizerType       = QuantizerType.UseSuppliedPalette;

            GifFrame frame
                = new GifFrame(Image.FromFile(@"images\smiley.bmp"));

            _e.AddFrame(frame);

            Assert.AreEqual(ColourTableStrategy.UseLocal, _e.ColourTableStrategy);
            Assert.AreEqual(QuantizerType.UseSuppliedPalette, _e.QuantizerType);

            frame.Palette = Palette.FromFile(@"ColourTables\gameboy.act");

            Assert.AreEqual(ColourTableStrategy.UseLocal, _e.ColourTableStrategy);
            Assert.AreEqual(QuantizerType.UseSuppliedPalette, _e.QuantizerType);

            _e.WriteToFile(GifFileName);

            _d = new GifDecoder(GifFileName);
            _d.Decode();

            Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState);

            ReportEnd();
        }
示例#2
0
 private void Encode()
 {
     // Note the encoder was instantiated in this form's constructor
     // and the user has set its properties in the UI, including adding
     // all the frames.
     try
     {
         _encoder.WriteToFile(_saveFileName);
         Invoke(new MethodInvoker(StopTheClock));
     }
     catch (Exception ex)
     {
         HandleException(ex);
     }
 }
示例#3
0
        public void TransparencyTest()
        {
            ReportStart();
            Color noColour    = Color.FromArgb(0, 0, 0, 0);            // note alpha of 0
            Color blue        = Color.FromArgb(0, 0, 255);
            Color transparent = Color.FromArgb(100, 100, 100);

            _encoder             = new AnimatedGifEncoder();
            _encoder.Transparent = transparent;

            // transparent | transparent
            // -------------------------
            // blue        | blue
            Bitmap bitmap = new Bitmap(2, 2);

            bitmap.SetPixel(0, 0, transparent);
            bitmap.SetPixel(1, 0, transparent);
            bitmap.SetPixel(0, 1, blue);
            bitmap.SetPixel(1, 1, blue);
            _frame = new GifFrame(bitmap);
            _encoder.AddFrame(_frame);

            // encode and decode
            string filename = "GifFrameTest.TransparencyTest.gif";

            _encoder.WriteToFile(filename);
            _decoder = new GifDecoder(filename);
            _decoder.Decode();
            Assert.AreEqual(ErrorState.Ok, _decoder.ConsolidatedState);

            // Result should be:
            // black | black
            // -------------
            // blue  | blue

            Bitmap actual = (Bitmap)_decoder.Frames[0].TheImage;

            Assert.AreEqual(noColour, actual.GetPixel(0, 0));
            Assert.AreEqual(noColour, actual.GetPixel(1, 0));
            Assert.AreEqual(blue, actual.GetPixel(0, 1));
            Assert.AreEqual(blue, actual.GetPixel(1, 1));

            ReportEnd();
        }
        private void TryDifferentPixelFormats()
        {
            Size size       = new Size(50, 50);
            int  blockiness = 10;

            PixelFormat[] pixelFormats = new PixelFormat[]
            {
                PixelFormat.Format16bppArgb1555,
                PixelFormat.Format16bppRgb555,
                PixelFormat.Format16bppRgb565,
                PixelFormat.Format24bppRgb,
                PixelFormat.Format32bppArgb,
                PixelFormat.Format32bppPArgb,
                PixelFormat.Format32bppRgb,
                PixelFormat.Format48bppRgb,
                PixelFormat.Format64bppArgb,
                PixelFormat.Format64bppPArgb,
            };
            foreach (PixelFormat pf in pixelFormats)
            {
                string formatName = pf.ToString();

                _encoder = new AnimatedGifEncoder();
                for (int i = 0; i < 10; i++)
                {
                    Bitmap bitmap = RandomBitmap.Create(size,
                                                        blockiness,
                                                        pf);
                    _encoder.AddFrame(new GifFrame(bitmap));
                }

                DateTime startTime = DateTime.Now;
                _encoder.WriteToFile(formatName + ".gif");
                DateTime endTime          = DateTime.Now;
                TimeSpan timeToEncode8bit = endTime - startTime;
                WriteMessage("Encoding " + formatName + " took " + timeToEncode8bit);
            }
        }
示例#5
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");
        }
示例#6
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);
        }
示例#7
0
        public void WikipediaExampleTest()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();
            GifFrame frame = new GifFrame(WikipediaExample.ExpectedBitmap);

            frame.Delay = WikipediaExample.DelayTime;
            _e.AddFrame(frame);

            // TODO: some way of creating/testing a UseLocal version of WikipediaExample
            string fileName = "WikipediaExampleUseGlobal.gif";

            _e.WriteToFile(fileName);
            Stream s = File.OpenRead(fileName);

            int code;

            // check GIF header
            GifHeader gh = new GifHeader(s);

            Assert.AreEqual(ErrorState.Ok, gh.ConsolidatedState);

            // check logical screen descriptor
            LogicalScreenDescriptor lsd = new LogicalScreenDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, lsd.ConsolidatedState);
            WikipediaExample.CheckLogicalScreenDescriptor(lsd);

            // read global colour table
            ColourTable gct
                = new ColourTable(s, WikipediaExample.GlobalColourTableSize);

            Assert.AreEqual(ErrorState.Ok, gct.ConsolidatedState);
            // cannot compare global colour table as different encoders will
            // produce difference colour tables.
//			WikipediaExample.CheckGlobalColourTable( gct );

            // check for extension introducer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeExtensionIntroducer, code);

            // check for app extension label
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeApplicationExtensionLabel, code);

            // check netscape extension
            ApplicationExtension ae = new ApplicationExtension(s);

            Assert.AreEqual(ErrorState.Ok, ae.ConsolidatedState);
            NetscapeExtension ne = new NetscapeExtension(ae);

            Assert.AreEqual(ErrorState.Ok, ne.ConsolidatedState);
            Assert.AreEqual(0, ne.LoopCount);

            // check for extension introducer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeExtensionIntroducer, code);

            // check for gce label
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeGraphicControlLabel, code);

            // check graphic control extension
            GraphicControlExtension gce = new GraphicControlExtension(s);

            Assert.AreEqual(ErrorState.Ok, gce.ConsolidatedState);
            WikipediaExample.CheckGraphicControlExtension(gce);

            // check for image separator
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeImageSeparator, code);

            // check for image descriptor
            ImageDescriptor id = new ImageDescriptor(s);

            Assert.AreEqual(ErrorState.Ok, id.ConsolidatedState);
            WikipediaExample.CheckImageDescriptor(id);

            // read, decode and check image data
            // Cannot compare encoded LZW data directly as different encoders
            // will create different colour tables, so even if the bitmaps are
            // identical, the colour indices will be different
            int pixelCount = WikipediaExample.FrameSize.Width
                             * WikipediaExample.FrameSize.Height;
            TableBasedImageData tbid = new TableBasedImageData(s, pixelCount);

            for (int y = 0; y < WikipediaExample.LogicalScreenSize.Height; y++)
            {
                for (int x = 0; x < WikipediaExample.LogicalScreenSize.Width; x++)
                {
                    int i = (y * WikipediaExample.LogicalScreenSize.Width) + x;
                    Assert.AreEqual(WikipediaExample.ExpectedBitmap.GetPixel(x, y),
                                    gct[tbid.Pixels[i]],
                                    "X: " + x + ", Y: " + y);
                }
            }

            // Check for block terminator after image data
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(0x00, code);

            // check for GIF trailer
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(GifComponent.CodeTrailer, code);

            // check we're at the end of the stream
            code = ExampleComponent.CallRead(s);
            Assert.AreEqual(-1, code);
            s.Close();

            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState);
            BitmapAssert.AreEqual(WikipediaExample.ExpectedBitmap,
                                  (Bitmap)_d.Frames[0].TheImage,
                                  "");
            ReportEnd();
        }
示例#8
0
 private void DoEncode()
 {
     _e.WriteToFile("MockOrange.test.gif");
 }
示例#9
0
        public void CompareQuantizers()
        {
            ReportStart();

            string   fileName;
            DateTime startTime;
            DateTime endTime;
            TimeSpan encodingTime;

            // Test actual quantization using image with 256+ colours.
            string bitmapFileName = "images/" + TestFixtureName
                                    + "." + TestCaseName + ".bmp";

            Bitmap b = new Bitmap(bitmapFileName);

            for (int q = 1; q <= 20; q++)
            {
                _e = new AnimatedGifEncoder();
                _e.QuantizerType  = QuantizerType.NeuQuant;
                _e.SamplingFactor = q;
                _e.AddFrame(new GifFrame(b));
                fileName  = TestFixtureName + "." + TestCaseName + ".NeuQuant." + q + ".gif";
                startTime = DateTime.Now;
                _e.WriteToFile(fileName);
                endTime      = DateTime.Now;
                encodingTime = endTime - startTime;
                WriteMessage("Encoding with quantization using NeuQuant, quality="
                             + q + " took " + encodingTime);
                _d = new GifDecoder(fileName);
                _d.Decode();
                Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState, "Quality " + q);
                Assert.AreEqual(1, _d.Frames.Count, "Quality " + q);
                // FIXME: NeuQuant quantizer reducing to 180 colours instead of 256 colours
                // TODO: Check for exactly 256 colours once Octree quantizer returns 256-colour images
//				Assert.AreEqual( 256, ImageTools.GetDistinctColours( colours ).Count );
                Assert.LessOrEqual(ImageTools.GetDistinctColours(_d.Frames[0].TheImage).Count, 256);
                for (int tolerance = 0; tolerance < 256; tolerance++)
                {
                    try
                    {
                        ImageAssert.AreEqual(b,
                                             _d.Frames[0].TheImage,
                                             tolerance,
                                             "Quality " + q);
                        WriteMessage("Quality " + q
                                     + " required tolerance " + tolerance);
                        break;
                    }
                    catch (AssertionExtensionException)
                    {
                        if (tolerance == 255)
                        {
                            throw;
                        }
                    }
                }
            }

            _e = new AnimatedGifEncoder();
            _e.QuantizerType = QuantizerType.Octree;
            _e.AddFrame(new GifFrame(b));
            fileName  = TestFixtureName + "." + TestCaseName + ".Octree.gif";
            startTime = DateTime.Now;
            _e.WriteToFile(fileName);
            endTime      = DateTime.Now;
            encodingTime = endTime - startTime;
            WriteMessage("Encoding with quantization using Octree took " + encodingTime);
            _d = new GifDecoder(fileName);
            _d.Decode();
            Assert.AreEqual(ErrorState.Ok, _d.ConsolidatedState);
            Assert.AreEqual(1, _d.Frames.Count);
            // FIXME: Octree quantizer should return a 256-colour image here
//			Assert.AreEqual( 256, ImageTools.GetDistinctColours( colours2 ).Count );
            Assert.LessOrEqual(ImageTools.GetDistinctColours(_d.Frames[0].TheImage).Count, 256);
            for (int tolerance = 0; tolerance < 256; tolerance++)
            {
                try
                {
                    ImageAssert.AreEqual(b,
                                         _d.Frames[0].TheImage,
                                         tolerance,
                                         "Octree");
                    WriteMessage("Octree quantization required tolerance "
                                 + tolerance);
                    break;
                }
                catch (AssertionExtensionException)
                {
                    if (tolerance == 255)
                    {
                        throw;
                    }
                }
            }

            // re-encoding an existing GIF should not cause quantization
            _d = new GifDecoder(@"images\globe\spinning globe better 200px transparent background.gif");
            _d.Decode();

            _e = new AnimatedGifEncoder();
            // NB OctreeQuantizer does not support global colour tables (yet!)
            _e.ColourTableStrategy = ColourTableStrategy.UseLocal;
            foreach (GifFrame f in _d.Frames)
            {
                _e.AddFrame(new GifFrame(f.TheImage));
            }

            fileName         = "NeuQuant.gif";
            _e.QuantizerType = QuantizerType.NeuQuant;
            startTime        = DateTime.Now;
            _e.WriteToFile(fileName);
            endTime      = DateTime.Now;
            encodingTime = endTime - startTime;
            WriteMessage("Encoding without quantization using NeuQuant took " + encodingTime);

            fileName         = "Octree.gif";
            _e.QuantizerType = QuantizerType.Octree;
            startTime        = DateTime.Now;
            _e.WriteToFile(fileName);
            endTime      = DateTime.Now;
            encodingTime = endTime - startTime;
            WriteMessage("Encoding without quantization using Octree took " + encodingTime);

            GifDecoder nqDecoder = new GifDecoder("NeuQuant.gif");

            nqDecoder.Decode();
            GifDecoder otDecoder = new GifDecoder("Octree.gif");

            otDecoder.Decode();
            Assert.AreEqual(nqDecoder.Frames.Count, otDecoder.Frames.Count);
            for (int i = 0; i < nqDecoder.Frames.Count; i++)
            {
                ImageAssert.AreEqual(nqDecoder.Frames[i].TheImage,
                                     otDecoder.Frames[i].TheImage,
                                     "frame " + i);
            }

            ReportEnd();
        }
        public void Bug2892015()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();

            #region create 10 random bitmaps
            Collection<Bitmap> bitmaps = new Collection<Bitmap>();
            for( int i = 0; i < 10; i++ )
            {
                Bitmap bitmap = RandomBitmap.Create( new Size( 50, 50 ),
                                                     10,
                                                     PixelFormat.Format32bppRgb );
                bitmaps.Add( bitmap );
            }
            #endregion

            DateTime startTime;
            DateTime endTime;

            #region create animation using just the first 3 (this should be quick)
            for( int i = 0; i < 3; i++ )
            {
                _e.AddFrame( new GifFrame( bitmaps[i] ) );
            }

            startTime = DateTime.Now;
            _e.WriteToFile( "2892015-1.gif" );
            endTime = DateTime.Now;
            TimeSpan runTime1 = endTime - startTime;
            WriteMessage( "Encoding 3 frames took " + runTime1 );
            #endregion

            _e.Frames.Clear();

            #region create animation using all the bitmaps (this will take longer)
            foreach( Bitmap bitmap in bitmaps )
            {
                _e.AddFrame( new GifFrame( bitmap ) );
            }

            startTime = DateTime.Now;
            _e.WriteToFile( "2892015-2.gif" );
            endTime = DateTime.Now;
            TimeSpan runTime2 = endTime - startTime;
            WriteMessage( "Encoding all " + bitmaps.Count + " frames took " + runTime2 );
            #endregion

            _e.Frames.Clear();

            #region create animation using just the first 3 (this should be quick)
            for( int i = 0; i < 3; i++ )
            {
                _e.AddFrame( new GifFrame( bitmaps[i] ) );
            }

            startTime = DateTime.Now;
            _e.WriteToFile( "2892015-3.gif" );
            endTime = DateTime.Now;
            TimeSpan runTime3 = endTime - startTime;
            WriteMessage( "Encoding 3 frames took " + runTime3 );
            #endregion

            Assert.IsTrue( runTime3 < runTime2 );
            _d = new GifDecoder( "2892015-3.gif" );
            _d.Decode();
            Assert.AreEqual( 3, _d.Frames.Count );

            ReportEnd();
        }
        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 );
        }
示例#12
0
        public static void ExtractAnimation(WzSubProperty parent, string savePath, bool apng, bool apngFirstFrame)
        {
            List <Bitmap> bmpList                    = new List <Bitmap>(parent.WzProperties.Count);
            List <int>    delayList                  = new List <int>(parent.WzProperties.Count);
            Point         biggestPng                 = new Point(0, 0);
            Point         SmallestEmptySpace         = new Point(65535, 65535);
            Point         MaximumPngMappingEndingPts = new Point(0, 0);

            foreach (IWzImageProperty subprop in parent.WzProperties)
            {
                if (subprop is WzCanvasProperty)
                {
                    //WzVectorProperty origin = (WzVectorProperty)subprop["origin"];
                    WzPngProperty png = ((WzCanvasProperty)subprop).PngProperty;
                    if (png.Height > biggestPng.Y)
                    {
                        biggestPng.Y = png.Height;
                    }
                    if (png.Width > biggestPng.X)
                    {
                        biggestPng.X = png.Width;
                    }
                }
            }
            List <WzCanvasProperty> sortedProps = new List <WzCanvasProperty>();

            foreach (IWzImageProperty subprop in parent.WzProperties)
            {
                if (subprop is WzCanvasProperty)
                {
                    sortedProps.Add((WzCanvasProperty)subprop);
                    WzPngProperty    png                  = ((WzCanvasProperty)subprop).PngProperty;
                    WzVectorProperty origin               = (WzVectorProperty)subprop["origin"];
                    Point            StartPoints          = new Point(biggestPng.X - origin.X.Value, biggestPng.Y - origin.Y.Value);
                    Point            PngMapppingEndingPts = new Point(StartPoints.X + png.Width, StartPoints.Y + png.Height);
                    if (StartPoints.X < SmallestEmptySpace.X)
                    {
                        SmallestEmptySpace.X = StartPoints.X;
                    }
                    if (StartPoints.Y < SmallestEmptySpace.Y)
                    {
                        SmallestEmptySpace.Y = StartPoints.Y;
                    }
                    if (PngMapppingEndingPts.X > MaximumPngMappingEndingPts.X)
                    {
                        MaximumPngMappingEndingPts.X = PngMapppingEndingPts.X;
                    }
                    if (PngMapppingEndingPts.Y > MaximumPngMappingEndingPts.Y)
                    {
                        MaximumPngMappingEndingPts.Y = PngMapppingEndingPts.Y;
                    }
                }
            }
            sortedProps.Sort(new Comparison <WzCanvasProperty>(PropertySorter));

/*            foreach (IWzImageProperty subprop in parent.WzProperties)
 *          {
 *              if (subprop is WzCanvasProperty)
 *              {
 *                  WzCompressedIntProperty delayProp = (WzCompressedIntProperty)subprop["delay"];
 *                  if (delayProp != null) delay = delayProp.Value;
 *              }
 *          }*/
/*            Brush bgcolor = null;
 *          switch (toolStripComboBox2.SelectedIndex)
 *          {
 *              case 0:
 *                  bgcolor = Brushes.Widthhite;
 *                  break;
 *              case 1:
 *                  bgcolor = Brushes.Black;
 *                  break;
 *              default:
 *                  bgcolor = Brushes.Black;
 *                  break;
 *          }*/

            for (int i = 0; i < sortedProps.Count; i++)
            {
                WzCanvasProperty subprop = sortedProps[i];
                if (i.ToString() != subprop.Name)
                {
                    Warning.Error("Something f****d up at animation builder, frame " + i.ToString());
                    return;
                }
                Bitmap           bmp    = subprop.PngProperty.GetPNG(false);
                WzVectorProperty origin = (WzVectorProperty)subprop["origin"];
//                    if (apng)
                bmpList.Add(OptimizeBitmapTransparent(bmp, origin, biggestPng, SmallestEmptySpace, MaximumPngMappingEndingPts));

/*                    else
 *                      bmpList.Add(OptimizeBitmap(bmp, origin, biggestPng, SmallestEmptySpace, MaximumPngMappingEndingPts, bgcolor));*/
                WzCompressedIntProperty delayProp = (WzCompressedIntProperty)subprop["delay"];
                int delay = 100;
                if (delayProp != null)
                {
                    delay = delayProp.Value;
                }
                delayList.Add(delay);
                //}
            }
            if (apng)
            {
                //List<Frame> frameList = new List<Frame>();

                /*                List<int> delayList = new List<int>();
                 *              foreach (TreeNode subnode in parent.Nodes)
                 *              {
                 *                  if (subnode.Tag2 is PNG)
                 *                  {
                 *                      TreeNode delayNode = FindNodeInSubnodes(subnode, "delay");
                 *                      if (delayNode == null) delayList.Add(0);
                 *                      else delayList.Add((int)delayNode.Tag2);
                 *                  }
                 *              }
                 *              if (delayList.Count != bmp.Count)
                 *              {
                 *                  MessageBox.Show("Weird error, seems like there are more PNGs than delay values");
                 *                  return;
                 *              }*/
                Apng apngBuilder = new Apng();
                if (apngFirstFrame)
                {
                    apngBuilder.AddFrame(new Frame(CreateIncompatibilityFrame(new Size(bmpList[0].Width, bmpList[0].Height)), 1, 1));
                }
                for (int i = 0; i < bmpList.Count; i++)
                {
                    apngBuilder.AddFrame(new Frame(bmpList[i], getNumByDelay(delayList[i]), getDenByDelay(delayList[i])));
                }
                apngBuilder.WriteApng(savePath, apngFirstFrame, true);
                //createapng(frameList, savePath);
            }
            else
            {
                AnimatedGifEncoder gifEncoder = new AnimatedGifEncoder();
                for (int i = 0; i < bmpList.Count; i++)
                {
                    gifEncoder.AddFrame(new GifFrame(bmpList[i])
                    {
                        Delay = delayList[i] / 10
                    });
                }
                gifEncoder.WriteToFile(savePath);
            }
        }
示例#13
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" );
        }
        public void BadEncodingUsingGameboyPaletteLocal()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();
            _e.ColourTableStrategy = ColourTableStrategy.UseLocal;
            _e.QuantizerType = QuantizerType.UseSuppliedPalette;

            GifFrame frame
                = new GifFrame( Image.FromFile( @"images\smiley.bmp" ) );
            _e.AddFrame( frame );

            Assert.AreEqual( ColourTableStrategy.UseLocal, _e.ColourTableStrategy );
            Assert.AreEqual( QuantizerType.UseSuppliedPalette, _e.QuantizerType );

            frame.Palette = Palette.FromFile( @"ColourTables\gameboy.act" );

            Assert.AreEqual( ColourTableStrategy.UseLocal, _e.ColourTableStrategy );
            Assert.AreEqual( QuantizerType.UseSuppliedPalette, _e.QuantizerType );

            _e.WriteToFile( GifFileName );

            _d = new GifDecoder( GifFileName );
            _d.Decode();

            Assert.AreEqual( ErrorState.Ok, _d.ConsolidatedState );

            ReportEnd();
        }
        public void WikipediaExampleTest()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();
            GifFrame frame = new GifFrame( WikipediaExample.ExpectedBitmap );
            frame.Delay = WikipediaExample.DelayTime;
            _e.AddFrame( frame );

            // TODO: some way of creating/testing a UseLocal version of WikipediaExample
            string fileName = "WikipediaExampleUseGlobal.gif";
            _e.WriteToFile( fileName );
            Stream s = File.OpenRead( fileName );

            int code;

            // check GIF header
            GifHeader gh = new GifHeader( s );
            Assert.AreEqual( ErrorState.Ok, gh.ConsolidatedState );

            // check logical screen descriptor
            LogicalScreenDescriptor lsd = new LogicalScreenDescriptor( s );
            Assert.AreEqual( ErrorState.Ok, lsd.ConsolidatedState );
            WikipediaExample.CheckLogicalScreenDescriptor( lsd );

            // read global colour table
            ColourTable gct
                = new ColourTable( s, WikipediaExample.GlobalColourTableSize );
            Assert.AreEqual( ErrorState.Ok, gct.ConsolidatedState );
            // cannot compare global colour table as different encoders will
            // produce difference colour tables.
            //			WikipediaExample.CheckGlobalColourTable( gct );

            // check for extension introducer
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( GifComponent.CodeExtensionIntroducer, code );

            // check for app extension label
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( GifComponent.CodeApplicationExtensionLabel, code );

            // check netscape extension
            ApplicationExtension ae = new ApplicationExtension( s );
            Assert.AreEqual( ErrorState.Ok, ae.ConsolidatedState );
            NetscapeExtension ne = new NetscapeExtension( ae );
            Assert.AreEqual( ErrorState.Ok, ne.ConsolidatedState );
            Assert.AreEqual( 0, ne.LoopCount );

            // check for extension introducer
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( GifComponent.CodeExtensionIntroducer, code );

            // check for gce label
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( GifComponent.CodeGraphicControlLabel, code );

            // check graphic control extension
            GraphicControlExtension gce = new GraphicControlExtension( s );
            Assert.AreEqual( ErrorState.Ok, gce.ConsolidatedState );
            WikipediaExample.CheckGraphicControlExtension( gce );

            // check for image separator
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( GifComponent.CodeImageSeparator, code );

            // check for image descriptor
            ImageDescriptor id = new ImageDescriptor( s );
            Assert.AreEqual( ErrorState.Ok, id.ConsolidatedState );
            WikipediaExample.CheckImageDescriptor( id );

            // read, decode and check image data
            // Cannot compare encoded LZW data directly as different encoders
            // will create different colour tables, so even if the bitmaps are
            // identical, the colour indices will be different
            int pixelCount = WikipediaExample.FrameSize.Width
                            * WikipediaExample.FrameSize.Height;
            TableBasedImageData tbid = new TableBasedImageData( s, pixelCount );
            for( int y = 0; y < WikipediaExample.LogicalScreenSize.Height; y++ )
            {
                for( int x = 0; x < WikipediaExample.LogicalScreenSize.Width; x++ )
                {
                    int i = (y * WikipediaExample.LogicalScreenSize.Width) + x;
                    Assert.AreEqual( WikipediaExample.ExpectedBitmap.GetPixel( x, y ),
                                     gct[tbid.Pixels[i]],
                                     "X: " + x + ", Y: " + y );
                }
            }

            // Check for block terminator after image data
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( 0x00, code );

            // check for GIF trailer
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( GifComponent.CodeTrailer, code );

            // check we're at the end of the stream
            code = ExampleComponent.CallRead( s );
            Assert.AreEqual( -1, code );
            s.Close();

            _d = new GifDecoder( fileName );
            _d.Decode();
            Assert.AreEqual( ErrorState.Ok, _d.ConsolidatedState );
            BitmapAssert.AreEqual( WikipediaExample.ExpectedBitmap,
                                  (Bitmap) _d.Frames[0].TheImage,
                                   "" );
            ReportEnd();
        }
        public void CompareQuantizers()
        {
            ReportStart();

            string fileName;
            DateTime startTime;
            DateTime endTime;
            TimeSpan encodingTime;

            // Test actual quantization using image with 256+ colours.
            string bitmapFileName = "images/" + TestFixtureName
                                   + "." + TestCaseName + ".bmp";

            Bitmap b = new Bitmap( bitmapFileName );

            for( int q = 1; q <= 20; q++ )
            {
                _e = new AnimatedGifEncoder();
                _e.QuantizerType = QuantizerType.NeuQuant;
                _e.SamplingFactor = q;
                _e.AddFrame( new GifFrame( b ) );
                fileName = TestFixtureName + "." + TestCaseName + ".NeuQuant." + q + ".gif";
                startTime = DateTime.Now;
                _e.WriteToFile( fileName );
                endTime = DateTime.Now;
                encodingTime = endTime - startTime;
                WriteMessage( "Encoding with quantization using NeuQuant, quality="
                              + q + " took " + encodingTime );
                _d = new GifDecoder( fileName );
                _d.Decode();
                Assert.AreEqual( ErrorState.Ok, _d.ConsolidatedState, "Quality " + q );
                Assert.AreEqual( 1, _d.Frames.Count, "Quality " + q );
                // FIXME: NeuQuant quantizer reducing to 180 colours instead of 256 colours
                // TODO: Check for exactly 256 colours once Octree quantizer returns 256-colour images
            //				Assert.AreEqual( 256, ImageTools.GetDistinctColours( colours ).Count );
                Assert.LessOrEqual( ImageTools.GetDistinctColours( _d.Frames[0].TheImage ).Count, 256 );
                for( int tolerance = 0; tolerance < 256; tolerance++ )
                {
                    try
                    {
                        ImageAssert.AreEqual( b,
                                              _d.Frames[0].TheImage,
                                              tolerance,
                                              "Quality " + q );
                        WriteMessage( "Quality " + q
                                     + " required tolerance " + tolerance );
                        break;
                    }
                    catch( AssertionExtensionException )
                    {
                        if( tolerance == 255 )
                        {
                            throw;
                        }
                    }
                }
            }

            _e = new AnimatedGifEncoder();
            _e.QuantizerType = QuantizerType.Octree;
            _e.AddFrame( new GifFrame( b ) );
            fileName = TestFixtureName + "." + TestCaseName + ".Octree.gif";
            startTime = DateTime.Now;
            _e.WriteToFile( fileName );
            endTime = DateTime.Now;
            encodingTime = endTime - startTime;
            WriteMessage( "Encoding with quantization using Octree took " + encodingTime );
            _d = new GifDecoder( fileName );
            _d.Decode();
            Assert.AreEqual( ErrorState.Ok, _d.ConsolidatedState );
            Assert.AreEqual( 1, _d.Frames.Count );
            // FIXME: Octree quantizer should return a 256-colour image here
            //			Assert.AreEqual( 256, ImageTools.GetDistinctColours( colours2 ).Count );
            Assert.LessOrEqual( ImageTools.GetDistinctColours( _d.Frames[0].TheImage ).Count, 256 );
            for( int tolerance = 0; tolerance < 256; tolerance++ )
            {
                try
                {
                    ImageAssert.AreEqual( b,
                                          _d.Frames[0].TheImage,
                                          tolerance,
                                          "Octree" );
                    WriteMessage( "Octree quantization required tolerance "
                                 + tolerance );
                    break;
                }
                catch( AssertionExtensionException )
                {
                    if( tolerance == 255 )
                    {
                        throw;
                    }
                }
            }

            // re-encoding an existing GIF should not cause quantization
            _d = new GifDecoder( @"images\globe\spinning globe better 200px transparent background.gif" );
            _d.Decode();

            _e = new AnimatedGifEncoder();
            // NB OctreeQuantizer does not support global colour tables (yet!)
            _e.ColourTableStrategy = ColourTableStrategy.UseLocal;
            foreach( GifFrame f in _d.Frames )
            {
                _e.AddFrame( new GifFrame( f.TheImage ) );
            }

            fileName = "NeuQuant.gif";
            _e.QuantizerType = QuantizerType.NeuQuant;
            startTime = DateTime.Now;
            _e.WriteToFile( fileName );
            endTime = DateTime.Now;
            encodingTime = endTime - startTime;
            WriteMessage( "Encoding without quantization using NeuQuant took " + encodingTime );

            fileName = "Octree.gif";
            _e.QuantizerType = QuantizerType.Octree;
            startTime = DateTime.Now;
            _e.WriteToFile( fileName );
            endTime = DateTime.Now;
            encodingTime = endTime - startTime;
            WriteMessage( "Encoding without quantization using Octree took " + encodingTime );

            GifDecoder nqDecoder = new GifDecoder( "NeuQuant.gif" );
            nqDecoder.Decode();
            GifDecoder otDecoder = new GifDecoder( "Octree.gif" );
            otDecoder.Decode();
            Assert.AreEqual( nqDecoder.Frames.Count, otDecoder.Frames.Count );
            for( int i = 0; i < nqDecoder.Frames.Count; i++ )
            {
                ImageAssert.AreEqual( nqDecoder.Frames[i].TheImage,
                                      otDecoder.Frames[i].TheImage,
                                      "frame " + i );
            }

            ReportEnd();
        }
 private void EncodeBigFile()
 {
     _encoder.WriteToFile("Profile.gif");
 }
        public void TransparencyTest()
        {
            ReportStart();
            Color noColour = Color.FromArgb( 0, 0, 0, 0 ); // note alpha of 0
            Color blue = Color.FromArgb( 0, 0, 255 );
            Color transparent = Color.FromArgb( 100, 100, 100 );
            _encoder = new AnimatedGifEncoder();
            _encoder.Transparent = transparent;

            // transparent | transparent
            // -------------------------
            // blue        | blue
            Bitmap bitmap = new Bitmap( 2, 2 );
            bitmap.SetPixel( 0, 0, transparent );
            bitmap.SetPixel( 1, 0, transparent );
            bitmap.SetPixel( 0, 1, blue );
            bitmap.SetPixel( 1, 1, blue );
            _frame = new GifFrame( bitmap );
            _encoder.AddFrame( _frame );

            // encode and decode
            string filename = "GifFrameTest.TransparencyTest.gif";
            _encoder.WriteToFile( filename );
            _decoder = new GifDecoder( filename );
            _decoder.Decode();
            Assert.AreEqual( ErrorState.Ok, _decoder.ConsolidatedState );

            // Result should be:
            // black | black
            // -------------
            // blue  | blue

            Bitmap actual = (Bitmap) _decoder.Frames[0].TheImage;
            Assert.AreEqual( noColour, actual.GetPixel( 0, 0 ) );
            Assert.AreEqual( noColour, actual.GetPixel( 1, 0 ) );
            Assert.AreEqual( blue, actual.GetPixel( 0, 1 ) );
            Assert.AreEqual( blue, actual.GetPixel( 1, 1 ) );

            ReportEnd();
        }
示例#20
0
        public void Bug2892015()
        {
            ReportStart();
            _e = new AnimatedGifEncoder();

            #region create 10 random bitmaps
            Collection <Bitmap> bitmaps = new Collection <Bitmap>();
            for (int i = 0; i < 10; i++)
            {
                Bitmap bitmap = RandomBitmap.Create(new Size(50, 50),
                                                    10,
                                                    PixelFormat.Format32bppRgb);
                bitmaps.Add(bitmap);
            }
            #endregion

            DateTime startTime;
            DateTime endTime;

            #region create animation using just the first 3 (this should be quick)
            for (int i = 0; i < 3; i++)
            {
                _e.AddFrame(new GifFrame(bitmaps[i]));
            }

            startTime = DateTime.Now;
            _e.WriteToFile("2892015-1.gif");
            endTime = DateTime.Now;
            TimeSpan runTime1 = endTime - startTime;
            WriteMessage("Encoding 3 frames took " + runTime1);
            #endregion

            _e.Frames.Clear();

            #region create animation using all the bitmaps (this will take longer)
            foreach (Bitmap bitmap in bitmaps)
            {
                _e.AddFrame(new GifFrame(bitmap));
            }

            startTime = DateTime.Now;
            _e.WriteToFile("2892015-2.gif");
            endTime = DateTime.Now;
            TimeSpan runTime2 = endTime - startTime;
            WriteMessage("Encoding all " + bitmaps.Count + " frames took " + runTime2);
            #endregion

            _e.Frames.Clear();

            #region create animation using just the first 3 (this should be quick)
            for (int i = 0; i < 3; i++)
            {
                _e.AddFrame(new GifFrame(bitmaps[i]));
            }

            startTime = DateTime.Now;
            _e.WriteToFile("2892015-3.gif");
            endTime = DateTime.Now;
            TimeSpan runTime3 = endTime - startTime;
            WriteMessage("Encoding 3 frames took " + runTime3);
            #endregion

            Assert.IsTrue(runTime3 < runTime2);
            _d = new GifDecoder("2892015-3.gif");
            _d.Decode();
            Assert.AreEqual(3, _d.Frames.Count);

            ReportEnd();
        }
        private void TryDifferentPixelFormats()
        {
            Size size = new Size( 50, 50 );
            int blockiness = 10;
            PixelFormat[] pixelFormats = new PixelFormat[]
            {
                PixelFormat.Format16bppArgb1555,
                PixelFormat.Format16bppRgb555,
                PixelFormat.Format16bppRgb565,
                PixelFormat.Format24bppRgb,
                PixelFormat.Format32bppArgb,
                PixelFormat.Format32bppPArgb,
                PixelFormat.Format32bppRgb,
                PixelFormat.Format48bppRgb,
                PixelFormat.Format64bppArgb,
                PixelFormat.Format64bppPArgb,
            };
            foreach( PixelFormat pf in pixelFormats )
            {
                string formatName = pf.ToString();

                _encoder = new AnimatedGifEncoder();
                for( int i = 0; i < 10; i++ )
                {
                    Bitmap bitmap = RandomBitmap.Create( size,
                                                         blockiness,
                                                         pf );
                    _encoder.AddFrame( new GifFrame( bitmap ) );
                }

                DateTime startTime = DateTime.Now;
                _encoder.WriteToFile( formatName + ".gif" );
                DateTime endTime = DateTime.Now;
                TimeSpan timeToEncode8bit = endTime - startTime;
                WriteMessage( "Encoding " + formatName + " took " + timeToEncode8bit );
            }
        }