Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:DesktopSprites.SpriteManagement.AnimatedImage`1"/> class from a given file.
        /// </summary>
        /// <param name="path">The path to the file which contains the image to be loaded.</param>
        /// <param name="staticImageFactory">The method that creates a TFrame object for a non-GIF file.</param>
        /// <param name="frameFactory">The method used to construct a TFrame object for each frame in a GIF animation.</param>
        /// <param name="allowableDepths">The allowable set of depths for the raw buffer. Use as many as your output format permits. The
        /// Indexed8Bpp format is required.</param>
        public AnimatedImage(string path, Func <string, T> staticImageFactory,
                             BufferToImage <T> frameFactory, BitDepths allowableDepths)
        {
            FilePath = path;

            if (Path.GetExtension(path) == ".gif")
            {
                AnimatedImageFromGif(frameFactory, allowableDepths);
            }
            else
            {
                AnimatedImageFromStaticFormat(staticImageFactory);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an <see cref="T:DesktopSprites.SpriteManagement.AnimatedImage`1"/> from a GIF file.
        /// </summary>
        /// <param name="frameFactory">The method used to construct a TFrame object for each frame in a GIF animation.</param>
        /// <param name="allowableDepths">The allowable set of depths for the raw buffer. Use as many as your output format permits. The
        /// Indexed8Bpp format is required.</param>
        private void AnimatedImageFromGif(BufferToImage <T> frameFactory, BitDepths allowableDepths)
        {
            GifImage <T> gifImage;

            using (FileStream imageStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                gifImage = new GifImage <T>(imageStream, frameFactory, allowableDepths);

            Size          = gifImage.Size;
            LoopCount     = gifImage.Iterations;
            ImageDuration = gifImage.Duration;

            int frameCount       = gifImage.Frames.Length;
            var framesList       = new List <T>(frameCount);
            var durationsList    = new List <int>(frameCount);
            var frameIndexesList = new List <int>(frameCount);
            var frameHashesList  = new List <int>(frameCount);

            for (int sourceFrame = 0; sourceFrame < frameCount; sourceFrame++)
            {
                int frameDuration = gifImage.Frames[sourceFrame].Duration;

                // Decoding the GIF may have produced frames of zero duration, we can safely drop these.
                // If the file has all-zero durations, we're into the land of undefined behavior for animations.
                // If we get to the last frame and we have nothing so far, we'll use that just so there is something to display.
                // Alternatively, in an image with only one frame, then only this frame ever need be displayed.
                if (frameDuration == 0 && !(ImageDuration == 0 && sourceFrame == frameCount - 1))
                {
                    // Dispose of unused frame.
                    IDisposable disposable = gifImage.Frames[sourceFrame].Image as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                    continue;
                }

                durationsList.Add(frameDuration);

                // Determine if all frames share the same duration.
                if (sourceFrame == 0)
                {
                    commonFrameDuration = frameDuration;
                }
                else if (commonFrameDuration != frameDuration)
                {
                    commonFrameDuration = -1;
                }

                // Calculate the frame hash to check if a duplicate frame exists.
                // This will update our collection and given hash list appropriately.
                AddOrReuseFrame(gifImage.Frames[sourceFrame], framesList, frameIndexesList, frameHashesList);
            }

            frames = framesList.ToImmutableArray();
            if (frames.Length != frameIndexesList.Count)
            {
                frameIndexes = frameIndexesList.ToImmutableArray();
            }
            if (commonFrameDuration == -1)
            {
                durations = durationsList.ToImmutableArray();
            }
        }