コード例 #1
0
        /// <summary>
        /// Writes the graphics control extension to the stream.
        /// </summary>
        /// <param name="metaData">The metadata of the image or frame.</param>
        /// <param name="writer">The stream to write to.</param>
        /// <param name="transparencyIndex">The index of the color in the color palette to make transparent.</param>
        private void WriteGraphicalControlExtension(ImageFrameMetaData metaData, EndianBinaryWriter writer, int transparencyIndex)
        {
            var extension = new GifGraphicsControlExtension
            {
                DisposalMethod    = metaData.DisposalMethod,
                TransparencyFlag  = transparencyIndex > -1,
                TransparencyIndex = unchecked ((byte)transparencyIndex),
                DelayTime         = metaData.FrameDelay
            };

            // Write the intro.
            this.buffer[0] = GifConstants.ExtensionIntroducer;
            this.buffer[1] = GifConstants.GraphicControlLabel;
            this.buffer[2] = 4;
            writer.Write(this.buffer, 0, 3);

            var field = default(PackedField);

            field.SetBits(3, 3, (int)extension.DisposalMethod); // 1-3 : Reserved, 4-6 : Disposal

            // TODO: Allow this as an option.
            field.SetBit(6, false);                      // 7 : User input - 0 = none
            field.SetBit(7, extension.TransparencyFlag); // 8: Has transparent.

            writer.Write(field.Byte);
            writer.Write((ushort)extension.DelayTime);
            writer.Write(extension.TransparencyIndex);
            writer.Write(GifConstants.Terminator);
        }
コード例 #2
0
        private void EncodeGlobal <TPixel>(Image <TPixel> image, QuantizedFrame <TPixel> quantized, int transparencyIndex, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            var palleteQuantizer = new PaletteQuantizer(this.quantizer.Diffuser);

            for (int i = 0; i < image.Frames.Count; i++)
            {
                ImageFrame <TPixel> frame         = image.Frames[i];
                ImageFrameMetaData  metaData      = frame.MetaData;
                GifFrameMetaData    frameMetaData = metaData.GetFormatMetaData(GifFormat.Instance);
                this.WriteGraphicalControlExtension(frameMetaData, transparencyIndex, stream);
                this.WriteImageDescriptor(frame, false, stream);

                if (i == 0)
                {
                    this.WriteImageData(quantized, stream);
                }
                else
                {
                    using (QuantizedFrame <TPixel> paletteQuantized
                               = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration(), () => quantized.Palette).QuantizeFrame(frame))
                    {
                        this.WriteImageData(paletteQuantized, stream);
                    }
                }
            }
        }
コード例 #3
0
        public void CloneIsDeep()
        {
            var metaData             = new ImageFrameMetaData();
            ImageFrameMetaData clone = metaData.DeepClone();

            Assert.False(metaData.GetFormatMetaData(GifFormat.Instance).Equals(clone.GetFormatMetaData(GifFormat.Instance)));
        }
コード例 #4
0
        public void ConstructorImageFrameMetaData()
        {
            ImageFrameMetaData metaData = new ImageFrameMetaData();

            metaData.FrameDelay = 42;

            ImageFrameMetaData clone = new ImageFrameMetaData(metaData);

            Assert.Equal(42, clone.FrameDelay);
        }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
        /// </summary>
        /// <param name="width">The width of the image in pixels.</param>
        /// <param name="height">The height of the image in pixels.</param>
        /// <param name="metaData">The meta data.</param>
        internal ImageFrame(int width, int height, ImageFrameMetaData metaData)
        {
            Guard.MustBeGreaterThan(width, 0, nameof(width));
            Guard.MustBeGreaterThan(height, 0, nameof(height));
            Guard.NotNull(metaData, nameof(metaData));

            this.pixelBuffer = Buffer2D <TPixel> .CreateClean(width, height);

            this.MetaData = metaData;
        }
コード例 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
        /// </summary>
        /// <param name="memoryManager">The <see cref="MemoryManager"/> to use for buffer allocations.</param>
        /// <param name="width">The width of the image in pixels.</param>
        /// <param name="height">The height of the image in pixels.</param>
        /// <param name="metaData">The meta data.</param>
        internal ImageFrame(MemoryManager memoryManager, int width, int height, ImageFrameMetaData metaData)
        {
            Guard.NotNull(memoryManager, nameof(memoryManager));
            Guard.MustBeGreaterThan(width, 0, nameof(width));
            Guard.MustBeGreaterThan(height, 0, nameof(height));
            Guard.NotNull(metaData, nameof(metaData));

            this.MemoryManager = memoryManager;
            this.PixelBuffer   = memoryManager.AllocateClean2D <TPixel>(width, height);
            this.MetaData      = metaData;
        }
コード例 #7
0
        public void ConstructorImageFrameMetaData()
        {
            ImageFrameMetaData metaData = new ImageFrameMetaData();

            metaData.FrameDelay     = 42;
            metaData.DisposalMethod = DisposalMethod.RestoreToBackground;

            ImageFrameMetaData clone = new ImageFrameMetaData(metaData);

            Assert.Equal(42, clone.FrameDelay);
            Assert.Equal(DisposalMethod.RestoreToBackground, clone.DisposalMethod);
        }
コード例 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class wrapping an existing buffer.
        /// </summary>
        internal ImageFrame(
            Configuration configuration,
            int width,
            int height,
            IBuffer <TPixel> consumedBuffer,
            ImageFrameMetaData metaData)
        {
            Guard.NotNull(configuration, nameof(configuration));
            Guard.MustBeGreaterThan(width, 0, nameof(width));
            Guard.MustBeGreaterThan(height, 0, nameof(height));
            Guard.NotNull(metaData, nameof(metaData));

            this.configuration   = configuration;
            this.MemoryAllocator = configuration.MemoryAllocator;
            this.PixelBuffer     = new Buffer2D <TPixel>(consumedBuffer, width, height);
            this.MetaData        = metaData;
        }
コード例 #9
0
        public void ConstructorImageFrameMetaData()
        {
            const int frameDelay                   = 42;
            const int colorTableLength             = 128;
            const GifDisposalMethod disposalMethod = GifDisposalMethod.RestoreToBackground;

            var metaData = new ImageFrameMetaData();
            GifFrameMetaData gifFrameMetaData = metaData.GetFormatMetaData(GifFormat.Instance);

            gifFrameMetaData.FrameDelay       = frameDelay;
            gifFrameMetaData.ColorTableLength = colorTableLength;
            gifFrameMetaData.DisposalMethod   = disposalMethod;

            var clone = new ImageFrameMetaData(metaData);
            GifFrameMetaData cloneGifFrameMetaData = clone.GetFormatMetaData(GifFormat.Instance);

            Assert.Equal(frameDelay, cloneGifFrameMetaData.FrameDelay);
            Assert.Equal(colorTableLength, cloneGifFrameMetaData.ColorTableLength);
            Assert.Equal(disposalMethod, cloneGifFrameMetaData.DisposalMethod);
        }
コード例 #10
0
        private void EncodeLocal <TPixel>(Image <TPixel> image, QuantizedFrame <TPixel> quantized, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            ImageFrame <TPixel> previousFrame = null;
            GifFrameMetaData    previousMeta  = null;

            foreach (ImageFrame <TPixel> frame in image.Frames)
            {
                ImageFrameMetaData metaData      = frame.MetaData;
                GifFrameMetaData   frameMetaData = metaData.GetFormatMetaData(GifFormat.Instance);
                if (quantized is null)
                {
                    // Allow each frame to be encoded at whatever color depth the frame designates if set.
                    if (previousFrame != null && previousMeta.ColorTableLength != frameMetaData.ColorTableLength &&
                        frameMetaData.ColorTableLength > 0)
                    {
                        quantized = this.quantizer.CreateFrameQuantizer <TPixel>(
                            image.GetConfiguration(),
                            frameMetaData.ColorTableLength).QuantizeFrame(frame);
                    }
                    else
                    {
                        quantized = this.quantizer.CreateFrameQuantizer <TPixel>(image.GetConfiguration())
                                    .QuantizeFrame(frame);
                    }
                }

                this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(quantized.Palette.Length).Clamp(1, 8);
                this.WriteGraphicalControlExtension(frameMetaData, this.GetTransparentIndex(quantized), stream);
                this.WriteImageDescriptor(frame, true, stream);
                this.WriteColorTable(quantized, stream);
                this.WriteImageData(quantized, stream);

                quantized?.Dispose();
                quantized     = null; // So next frame can regenerate it
                previousFrame = frame;
                previousMeta  = frameMetaData;
            }
        }
コード例 #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
 /// </summary>
 /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
 /// <param name="size">The <see cref="Size"/> of the frame.</param>
 /// <param name="metaData">The meta data.</param>
 internal ImageFrame(Configuration configuration, Size size, ImageFrameMetaData metaData)
     : this(configuration, size.Width, size.Height, metaData)
 {
 }
コード例 #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageFrameMetaData"/> class
        /// by making a copy from other metadata.
        /// </summary>
        /// <param name="other">
        /// The other <see cref="ImageFrameMetaData"/> to create this instance from.
        /// </param>
        internal ImageFrameMetaData(ImageFrameMetaData other)
        {
            DebugGuard.NotNull(other, nameof(other));

            this.FrameDelay = other.FrameDelay;
        }
コード例 #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
        /// </summary>
        /// <param name="configuration">The <see cref="Configuration"/> to use for buffer allocation and parallel options to clear the buffer with.</param>
        /// <param name="width">The width of the image in pixels.</param>
        /// <param name="height">The height of the image in pixels.</param>
        /// <param name="backgroundColor">The color to clear the image with.</param>
        /// <param name="metaData">The meta data.</param>
        internal ImageFrame(Configuration configuration, int width, int height, TPixel backgroundColor, ImageFrameMetaData metaData)
        {
            Guard.NotNull(configuration, nameof(configuration));
            Guard.MustBeGreaterThan(width, 0, nameof(width));
            Guard.MustBeGreaterThan(height, 0, nameof(height));
            Guard.NotNull(metaData, nameof(metaData));

            this.MemoryManager = configuration.MemoryManager;
            this.PixelBuffer   = this.MemoryManager.Allocate2D <TPixel>(width, height, false);
            this.Clear(configuration.ParallelOptions, backgroundColor);
            this.MetaData = metaData;
        }
コード例 #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
 /// </summary>
 /// <param name="size">The <see cref="Size"/> of the frame.</param>
 /// <param name="metaData">The meta data.</param>
 internal ImageFrame(Size size, ImageFrameMetaData metaData)
     : this(size.Width, size.Height, metaData)
 {
 }
コード例 #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
 /// </summary>
 /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
 /// <param name="width">The width of the image in pixels.</param>
 /// <param name="height">The height of the image in pixels.</param>
 /// <param name="metaData">The meta data.</param>
 internal ImageFrame(Configuration configuration, int width, int height, ImageFrameMetaData metaData)
     : this(configuration, width, height, default(TPixel), metaData)
 {
 }
コード例 #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
        /// </summary>
        /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
        /// <param name="width">The width of the image in pixels.</param>
        /// <param name="height">The height of the image in pixels.</param>
        /// <param name="backgroundColor">The color to clear the image with.</param>
        /// <param name="metaData">The meta data.</param>
        internal ImageFrame(Configuration configuration, int width, int height, TPixel backgroundColor, ImageFrameMetaData metaData)
        {
            Guard.NotNull(configuration, nameof(configuration));
            Guard.MustBeGreaterThan(width, 0, nameof(width));
            Guard.MustBeGreaterThan(height, 0, nameof(height));

            this.configuration   = configuration;
            this.MemoryAllocator = configuration.MemoryAllocator;
            this.PixelBuffer     = this.MemoryAllocator.Allocate2D <TPixel>(width, height);
            this.MetaData        = metaData ?? new ImageFrameMetaData();
            this.Clear(configuration.GetParallelOptions(), backgroundColor);
        }
コード例 #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
 /// </summary>
 /// <param name="memoryManager">The <see cref="MemoryManager"/> to use for buffer allocations.</param>
 /// <param name="size">The <see cref="Size"/> of the frame.</param>
 /// <param name="metaData">The meta data.</param>
 internal ImageFrame(MemoryManager memoryManager, Size size, ImageFrameMetaData metaData)
     : this(memoryManager, size.Width, size.Height, metaData)
 {
 }