/// <summary>
        /// Applies the given processor the current image.
        /// </summary>
        /// <param name="processor">The processor delegate.</param>
        /// <param name="factory">The <see cref="ImageFactory" />.</param>
        public override void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory)
        {
            GifDecoder decoder = new GifDecoder(factory.Image, factory.AnimationProcessMode);
            Image factoryImage = factory.Image;
            GifEncoder encoder = new GifEncoder(null, null, decoder.LoopCount);

            for (int i = 0; i < decoder.FrameCount; i++)
            {
                GifFrame frame = decoder.GetFrame(factoryImage, i);
                factory.Image = frame.Image;
                frame.Image = this.Quantizer.Quantize(processor.Invoke(factory));
                encoder.AddFrame(frame);
            }

            factoryImage.Dispose();
            factory.Image = encoder.Save();
        }
Beispiel #2
0
        /// <inheritdoc />
        public override Image Save(string path, Image image, long bitDepth)
        {
            // Never use default save for gifs. It's terrible.
            using (FileStream fs = File.OpenWrite(path))
            {
                var decoder = new GifDecoder(image, AnimationProcessMode.All);
                var encoder = new GifEncoder(null, null, decoder.LoopCount);

                for (int i = 0; i < decoder.FrameCount; i++)
                {
                    GifFrame frame = decoder.GetFrame(image, i);
                    frame.Image = this.Quantizer.Quantize(frame.Image);
                    encoder.AddFrame(frame);
                }

                encoder.Save(fs);
                return(encoder.Save());
            }
        }
Beispiel #3
0
        /// <summary>
        /// Applies the given processor the current image.
        /// </summary>
        /// <param name="processor">The processor delegate.</param>
        /// <param name="factory">The <see cref="ImageFactory" />.</param>
        public override void ApplyProcessor(Func <ImageFactory, Image> processor, ImageFactory factory)
        {
            GifDecoder decoder = new GifDecoder(factory.Image);

            if (decoder.IsAnimated)
            {
                GifEncoder encoder = new GifEncoder(null, null, decoder.LoopCount);
                foreach (GifFrame frame in decoder.GifFrames)
                {
                    factory.Image = frame.Image;
                    frame.Image   = this.Quantizer.Quantize(processor.Invoke(factory));
                    encoder.AddFrame(frame);
                }

                factory.Image = encoder.Save();
            }
            else
            {
                base.ApplyProcessor(processor, factory);
            }
        }
        /// <summary>
        /// Creates a copy of an image allowing you to set the pixel format.
        /// Disposing of the original is the responsibility of the user.
        /// <remarks>
        /// Unlike the native <see cref="Image.Clone"/> method this also copies animation frames.
        /// </remarks>
        /// </summary>
        /// <param name="source">The source image to copy.</param>
        /// <param name="format">The <see cref="PixelFormat"/> to set the copied image to.</param>
        /// <returns>
        /// The <see cref="Image"/>.
        /// </returns>
        public static Image Copy(this Image source, PixelFormat format = PixelFormat.Format32bppPArgb)
        {
            if (FormatUtilities.IsAnimated(source))
            {
                // TODO: Ensure that we handle other animated types.
                GifDecoder decoder = new GifDecoder(source);
                GifEncoder encoder = new GifEncoder(null, null, decoder.LoopCount);
                foreach (GifFrame frame in decoder.GifFrames)
                {
                    frame.Image = ((Bitmap)frame.Image).Clone(new Rectangle(0, 0, frame.Image.Width, frame.Image.Height), format);
                    ((Bitmap)frame.Image).SetResolution(source.HorizontalResolution, source.VerticalResolution);
                    encoder.AddFrame(frame);
                }

                return encoder.Save();
            }

            Bitmap copy = ((Bitmap)source).Clone(new Rectangle(0, 0, source.Width, source.Height), format);
            copy.SetResolution(source.HorizontalResolution, source.VerticalResolution);
            return copy;
        }
        /// <summary>
        /// Creates a deep copy of an image allowing you to set the pixel format.
        /// Disposing of the original is the responsibility of the user.
        /// <remarks>
        /// Unlike the native <see cref="Image.Clone"/> method this also copies animation frames.
        /// </remarks>
        /// </summary>
        /// <param name="source">The source image to copy.</param>
        /// <param name="animationProcessMode">The process mode for frames in animated images.</param>
        /// <param name="format">The <see cref="PixelFormat"/> to set the copied image to.</param>
        /// <param name="preserveExifData">Whether to preserve exif metadata. Defaults to false.</param>
        /// <returns>
        /// The <see cref="Image"/>.
        /// </returns>
        public static Image Copy(this Image source, AnimationProcessMode animationProcessMode, PixelFormat format = PixelFormat.Format32bppPArgb, bool preserveExifData = false)
        {
            if (source.RawFormat.Equals(ImageFormat.Gif))
            {
                // Read from the correct first frame when performing additional processing
                source.SelectActiveFrame(FrameDimension.Time, 0);
                GifDecoder decoder = new GifDecoder(source, animationProcessMode);
                GifEncoder encoder = new GifEncoder(null, null, decoder.LoopCount);

                // Have to use Octree here, there's no way to inject it.
                OctreeQuantizer quantizer = new OctreeQuantizer();
                for (int i = 0; i < decoder.FrameCount; i++)
                {
                    GifFrame frame = decoder.GetFrame(source, i);
                    frame.Image = quantizer.Quantize(((Bitmap)frame.Image).Clone(new Rectangle(0, 0, frame.Image.Width, frame.Image.Height), format));
                    ((Bitmap)frame.Image).SetResolution(source.HorizontalResolution, source.VerticalResolution);
                    encoder.AddFrame(frame);
                }

                return encoder.Save();
            }

            // Create a new image and copy it's pixels.
            Bitmap copy = new Bitmap(source.Width, source.Height, format);
            copy.SetResolution(source.HorizontalResolution, source.VerticalResolution);
            using (Graphics graphics = Graphics.FromImage(copy))
            {
                graphics.DrawImageUnscaled(source, 0, 0);
            }

            if (preserveExifData)
            {
                foreach (PropertyItem item in source.PropertyItems)
                {
                    copy.SetPropertyItem(item);
                }
            }

            return copy;
        }
Beispiel #6
0
        /// <summary>
        /// Applies the given processor the current image.
        /// </summary>
        /// <param name="processor">The processor delegate.</param>
        /// <param name="factory">The <see cref="ImageFactory" />.</param>
        public override void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory)
        {
            GifDecoder decoder = new GifDecoder(factory.Image);
            if (decoder.IsAnimated)
            {
                GifEncoder encoder = new GifEncoder(null, null, decoder.LoopCount);
                foreach (GifFrame frame in decoder.GifFrames)
                {
                    factory.Image = frame.Image;
                    frame.Image = this.Quantizer.Quantize(processor.Invoke(factory));
                    encoder.AddFrame(frame);
                }

                factory.Image = encoder.Save();
            }
            else
            {
                base.ApplyProcessor(processor, factory);
            }
        }