private void EncodeGlobal <TPixel>(Image <TPixel> image, QuantizedFrame <TPixel> quantized, int transparencyIndex, Stream stream) where TPixel : struct, IPixel <TPixel> { var palleteQuantizer = new PaletteQuantizer <TPixel>(quantized.Palette, 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 (IFrameQuantizer <TPixel> palleteFrameQuantizer = palleteQuantizer.CreateFrameQuantizer(image.GetConfiguration())) using (QuantizedFrame <TPixel> paletteQuantized = palleteFrameQuantizer.QuantizeFrame(frame)) { this.WriteImageData(paletteQuantized, stream); } } } }
private void EncodeGlobal <TPixel>(Image <TPixel> image, IQuantizedFrame <TPixel> quantized, int transparencyIndex, Stream stream) where TPixel : struct, IPixel <TPixel> { for (int i = 0; i < image.Frames.Count; i++) { ImageFrame <TPixel> frame = image.Frames[i]; ImageFrameMetadata metadata = frame.Metadata; GifFrameMetadata frameMetadata = metadata.GetGifMetadata(); this.WriteGraphicalControlExtension(frameMetadata, transparencyIndex, stream); this.WriteImageDescriptor(frame, false, stream); if (i == 0) { this.WriteImageData(quantized, stream); } else { using (IFrameQuantizer <TPixel> paletteFrameQuantizer = new PaletteFrameQuantizer <TPixel>(this.quantizer.Diffuser, quantized.Palette)) { using (IQuantizedFrame <TPixel> paletteQuantized = paletteFrameQuantizer.QuantizeFrame(frame)) { this.WriteImageData(paletteQuantized, stream); } } } } }
private void EncodeGlobal <TPixel>(Image <TPixel> image, IndexedImageFrame <TPixel> quantized, int transparencyIndex, Stream stream) where TPixel : unmanaged, IPixel <TPixel> { // The palette quantizer can reuse the same pixel map across multiple frames // since the palette is unchanging. This allows a reduction of memory usage across // multi frame gifs using a global palette. EuclideanPixelMap <TPixel> pixelMap = default; bool pixelMapSet = false; for (int i = 0; i < image.Frames.Count; i++) { ImageFrame <TPixel> frame = image.Frames[i]; ImageFrameMetadata metadata = frame.Metadata; GifFrameMetadata frameMetadata = metadata.GetGifMetadata(); this.WriteGraphicalControlExtension(frameMetadata, transparencyIndex, stream); this.WriteImageDescriptor(frame, false, stream); if (i == 0) { this.WriteImageData(quantized, stream); } else { if (!pixelMapSet) { pixelMapSet = true; pixelMap = new EuclideanPixelMap <TPixel>(this.configuration, quantized.Palette); } using var paletteFrameQuantizer = new PaletteFrameQuantizer <TPixel>(this.configuration, this.quantizer.Options, pixelMap); using IndexedImageFrame <TPixel> paletteQuantized = paletteFrameQuantizer.QuantizeFrame(frame, frame.Bounds()); this.WriteImageData(paletteQuantized, stream); } } }
private void EncodeLocal <TPixel>(Image <TPixel> image, QuantizedFrame <TPixel> quantized, Stream stream) where TPixel : unmanaged, IPixel <TPixel> { ImageFrame <TPixel> previousFrame = null; GifFrameMetadata previousMeta = null; foreach (ImageFrame <TPixel> frame in image.Frames) { ImageFrameMetadata metadata = frame.Metadata; GifFrameMetadata frameMetadata = metadata.GetGifMetadata(); 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) { var options = new QuantizerOptions { Dither = this.quantizer.Options.Dither, DitherScale = this.quantizer.Options.DitherScale, MaxColors = frameMetadata.ColorTableLength }; using (IFrameQuantizer <TPixel> frameQuantizer = this.quantizer.CreateFrameQuantizer <TPixel>(this.configuration, options)) { quantized = frameQuantizer.QuantizeFrame(frame, frame.Bounds()); } } else { using (IFrameQuantizer <TPixel> frameQuantizer = this.quantizer.CreateFrameQuantizer <TPixel>(this.configuration)) { quantized = frameQuantizer.QuantizeFrame(frame, frame.Bounds()); } } } 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; } }
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; } }