/// <summary>
        /// Creates the quantized frame.
        /// </summary>
        /// <typeparam name="TPixel">The type of the pixel.</typeparam>
        /// <param name="options">The options.</param>
        /// <param name="image">The image.</param>
        public static IndexedImageFrame <TPixel> CreateQuantizedFrame <TPixel>(
            PngEncoderOptions options,
            Image <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            if (options.ColorType != PngColorType.Palette)
            {
                return(null);
            }

            // Use the metadata to determine what quantization depth to use if no quantizer has been set.
            if (options.Quantizer is null)
            {
                byte bits      = (byte)options.BitDepth;
                var  maxColors = ColorNumerics.GetColorCountForBitDepth(bits);
                options.Quantizer = new WuQuantizer(new QuantizerOptions {
                    MaxColors = maxColors
                });
            }

            // Create quantized frame returning the palette and set the bit depth.
            using (IQuantizer <TPixel> frameQuantizer = options.Quantizer.CreatePixelSpecificQuantizer <TPixel>(image.GetConfiguration()))
            {
                ImageFrame <TPixel> frame = image.Frames.RootFrame;
                return(frameQuantizer.BuildPaletteAndQuantizeFrame(frame, frame.Bounds()));
            }
        }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GifEncoderCore"/> class.
 /// </summary>
 /// <param name="memoryAllocator">The <see cref="MemoryAllocator"/> to use for buffer allocations.</param>
 /// <param name="options">The options for the encoder.</param>
 public GifEncoderCore(MemoryAllocator memoryAllocator, IGifEncoderOptions options)
 {
     this.memoryAllocator = memoryAllocator;
     this.textEncoding    = options.TextEncoding ?? GifConstants.DefaultEncoding;
     this.quantizer       = options.Quantizer;
     this.colorTableMode  = options.ColorTableMode;
 }
Пример #3
0
        public void OctreeQuantizerCanCreateFrameQuantizer()
        {
            var quantizer = new OctreeQuantizer();
            IQuantizer <Rgba32> frameQuantizer = quantizer.CreatePixelSpecificQuantizer <Rgba32>(Configuration.Default);

            Assert.NotNull(frameQuantizer);
            Assert.NotNull(frameQuantizer.Options);
            Assert.Equal(QuantizerConstants.DefaultDither, frameQuantizer.Options.Dither);
            frameQuantizer.Dispose();

            quantizer = new OctreeQuantizer(new QuantizerOptions {
                Dither = null
            });
            frameQuantizer = quantizer.CreatePixelSpecificQuantizer <Rgba32>(Configuration.Default);

            Assert.NotNull(frameQuantizer);
            Assert.Null(frameQuantizer.Options.Dither);
            frameQuantizer.Dispose();

            quantizer = new OctreeQuantizer(new QuantizerOptions {
                Dither = KnownDitherings.Atkinson
            });
            frameQuantizer = quantizer.CreatePixelSpecificQuantizer <Rgba32>(Configuration.Default);
            Assert.NotNull(frameQuantizer);
            Assert.Equal(KnownDitherings.Atkinson, frameQuantizer.Options.Dither);
            frameQuantizer.Dispose();
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GifEncoderCore"/> class.
 /// </summary>
 /// <param name="memoryManager">The <see cref="MemoryManager"/> to use for buffer allocations.</param>
 /// <param name="options">The options for the encoder.</param>
 public GifEncoderCore(MemoryManager memoryManager, IGifEncoderOptions options)
 {
     this.memoryManager  = memoryManager;
     this.textEncoding   = options.TextEncoding ?? GifConstants.DefaultEncoding;
     this.quantizer      = options.Quantizer;
     this.ignoreMetadata = options.IgnoreMetadata;
 }
Пример #5
0
        public void Init()
        {
            var config = TestHelper.GetFakeConfig().Object;

            _extractor = new MorphologyExtractor(config);
            _quantizer = new MorphologyQuantizer(config);
        }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BmpEncoderCore"/> class.
 /// </summary>
 /// <param name="options">The encoder options.</param>
 /// <param name="memoryAllocator">The memory manager.</param>
 public BmpEncoderCore(IBmpEncoderOptions options, MemoryAllocator memoryAllocator)
 {
     this.memoryAllocator = memoryAllocator;
     this.bitsPerPixel    = options.BitsPerPixel;
     this.writeV4Header   = options.SupportTransparency;
     this.quantizer       = options.Quantizer ?? KnownQuantizers.Octree;
 }
Пример #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BmpEncoderCore"/> class.
 /// </summary>
 /// <param name="options">The encoder options.</param>
 /// <param name="memoryAllocator">The memory manager.</param>
 public BmpEncoderCore(IBmpEncoderOptions options, MemoryAllocator memoryAllocator)
 {
     this.memoryAllocator = memoryAllocator;
     this.bitsPerPixel    = options.BitsPerPixel;
     this.writeV4Header   = options.SupportTransparency;
     this.quantizer       = options.Quantizer ?? new OctreeQuantizer(dither: true, maxColors: 256);
 }
Пример #8
0
 public void Init()
 {
     _matcher        = new MorphologyMatcher();
     _boardExtractor = new BoardExtractor(_matcher);
     _quantizer      = new MorphologyQuantizer(TestHelper.GetFakeConfig().Object);
     _initialBoard   = TestHelper.BuildBoard(new[]
     {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
         0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
         0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
         0, 1, 1, 1, 0, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 0, 1, 1, 1, 1, 1
     });
 }
Пример #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GifEncoderCore"/> class.
 /// </summary>
 /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
 /// <param name="options">The options for the encoder.</param>
 public GifEncoderCore(Configuration configuration, IGifEncoderOptions options)
 {
     this.configuration   = configuration;
     this.memoryAllocator = configuration.MemoryAllocator;
     this.quantizer       = options.Quantizer;
     this.colorTableMode  = options.ColorTableMode;
 }
Пример #10
0
        public TiffPaletteWriter(
            ImageFrame <TPixel> image,
            IQuantizer quantizer,
            MemoryAllocator memoryAllocator,
            Configuration configuration,
            TiffEncoderEntriesCollector entriesCollector,
            int bitsPerPixel)
            : base(image, memoryAllocator, configuration, entriesCollector)
        {
            DebugGuard.NotNull(quantizer, nameof(quantizer));
            DebugGuard.NotNull(configuration, nameof(configuration));
            DebugGuard.NotNull(entriesCollector, nameof(entriesCollector));
            DebugGuard.MustBeBetweenOrEqualTo(bitsPerPixel, 4, 8, nameof(bitsPerPixel));

            this.BitsPerPixel      = bitsPerPixel;
            this.maxColors         = this.BitsPerPixel == 4 ? 16 : 256;
            this.colorPaletteSize  = this.maxColors * 3;
            this.colorPaletteBytes = this.colorPaletteSize * 2;
            using IQuantizer <TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer <TPixel>(this.Configuration, new QuantizerOptions()
            {
                MaxColors = this.maxColors
            });
            this.quantizedImage = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds());

            this.AddColorMapTag();
        }
Пример #11
0
        public void QuantizersDitherByDefault()
        {
            var werner  = new WernerPaletteQuantizer();
            var webSafe = new WebSafePaletteQuantizer();
            var octree  = new OctreeQuantizer();
            var wu      = new WuQuantizer();

            Assert.NotNull(werner.Options.Dither);
            Assert.NotNull(webSafe.Options.Dither);
            Assert.NotNull(octree.Options.Dither);
            Assert.NotNull(wu.Options.Dither);

            using (IQuantizer <Rgba32> quantizer = werner.CreatePixelSpecificQuantizer <Rgba32>(this.Configuration))
            {
                Assert.NotNull(quantizer.Options.Dither);
            }

            using (IQuantizer <Rgba32> quantizer = webSafe.CreatePixelSpecificQuantizer <Rgba32>(this.Configuration))
            {
                Assert.NotNull(quantizer.Options.Dither);
            }

            using (IQuantizer <Rgba32> quantizer = octree.CreatePixelSpecificQuantizer <Rgba32>(this.Configuration))
            {
                Assert.NotNull(quantizer.Options.Dither);
            }

            using (IQuantizer <Rgba32> quantizer = wu.CreatePixelSpecificQuantizer <Rgba32>(this.Configuration))
            {
                Assert.NotNull(quantizer.Options.Dither);
            }
        }
Пример #12
0
        /// <summary>
        /// Applies quantization to the image.
        /// </summary>
        /// <typeparam name="TColor">The pixel format.</typeparam>
        /// <param name="source">The image this method extends.</param>
        /// <param name="quantizer">The quantizer to apply to perform the operation.</param>
        /// <param name="maxColors">The maximum number of colors to return.</param>
        /// <returns>The <see cref="Image{TColor}"/>.</returns>
        public static Image <TColor> Quantize <TColor>(this Image <TColor> source, IQuantizer <TColor> quantizer, int maxColors)
            where TColor : struct, IPackedPixel, IEquatable <TColor>
        {
            QuantizedImage <TColor> quantized = quantizer.Quantize(source, maxColors);
            int palleteCount = quantized.Palette.Length - 1;

            using (PixelAccessor <TColor> pixels = new PixelAccessor <TColor>(quantized.Width, quantized.Height))
            {
                Parallel.For(
                    0,
                    pixels.Height,
                    source.Configuration.ParallelOptions,
                    y =>
                {
                    for (int x = 0; x < pixels.Width; x++)
                    {
                        int i        = x + (y * pixels.Width);
                        TColor color = quantized.Palette[Math.Min(palleteCount, quantized.Pixels[i])];
                        pixels[x, y] = color;
                    }
                });

                source.SwapPixelsBuffers(pixels);
                return(source);
            }
        }
Пример #13
0
        private static void TestBmpEncoderCore <TPixel>(
            TestImageProvider <TPixel> provider,
            BmpBitsPerPixel bitsPerPixel,
            bool supportTransparency     = true, // if set to true, will write a V4 header, otherwise a V3 header.
            IQuantizer quantizer         = null,
            ImageComparer customComparer = null)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            using (Image <TPixel> image = provider.GetImage())
            {
                // There is no alpha in bmp with less then 32 bits per pixels, so the reference image will be made opaque.
                if (bitsPerPixel != BmpBitsPerPixel.Pixel32)
                {
                    image.Mutate(c => c.MakeOpaque());
                }

                var encoder = new BmpEncoder
                {
                    BitsPerPixel        = bitsPerPixel,
                    SupportTransparency = supportTransparency,
                    Quantizer           = quantizer ?? KnownQuantizers.Octree
                };

                // Does DebugSave & load reference CompareToReferenceInput():
                image.VerifyEncoder(provider, "bmp", bitsPerPixel, encoder, customComparer);
            }
        }
Пример #14
0
        internal void PerformDraw(IQuantizer quantizer, IDitherer ditherer)
        {
            if (quantizer == null)
            {
                PerformDrawDirect();
                return;
            }

            IReadableBitmapData initSource = SourceRectangle.Size == Source.GetSize()
                ? Source
                : Source.Clip(SourceRectangle);

            try
            {
                Debug.Assert(!quantizer.InitializeReliesOnContent || !Source.HasMultiLevelAlpha(), "This draw performs blending on-the-fly but the used quantizer would require two-pass processing");
                context.Progress?.New(DrawingOperation.InitializingQuantizer);
                using (IQuantizingSession quantizingSession = quantizer.Initialize(initSource, context))
                {
                    if (context.IsCancellationRequested)
                    {
                        return;
                    }
                    if (quantizingSession == null)
                    {
                        throw new InvalidOperationException(Res.ImagingQuantizerInitializeNull);
                    }

                    // quantizing without dithering
                    if (ditherer == null)
                    {
                        PerformDrawWithQuantizer(quantizingSession);
                        return;
                    }

                    // quantizing with dithering
                    Debug.Assert(!ditherer.InitializeReliesOnContent || !Source.HasMultiLevelAlpha(), "This draw performs blending on-the-fly but the used ditherer would require two-pass processing");

                    context.Progress?.New(DrawingOperation.InitializingDitherer);
                    using IDitheringSession ditheringSession = ditherer.Initialize(initSource, quantizingSession, context);
                    if (context.IsCancellationRequested)
                    {
                        return;
                    }
                    if (ditheringSession == null)
                    {
                        throw new InvalidOperationException(Res.ImagingDithererInitializeNull);
                    }

                    PerformDrawWithDithering(quantizingSession, ditheringSession);
                }
            }
            finally
            {
                if (!ReferenceEquals(initSource, Source))
                {
                    initSource.Dispose();
                }
            }
        }
Пример #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GifEncoderCore"/> class.
 /// </summary>
 /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
 /// <param name="options">The options for the encoder.</param>
 public GifEncoderCore(Configuration configuration, IGifEncoderOptions options)
 {
     this.configuration         = configuration;
     this.memoryAllocator       = configuration.MemoryAllocator;
     this.quantizer             = options.Quantizer;
     this.colorTableMode        = options.ColorTableMode;
     this.pixelSamplingStrategy = options.GlobalPixelSamplingStrategy;
 }
Пример #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QuantizeProcessor{TPixel}"/> class.
        /// </summary>
        /// <param name="quantizer">The quantizer used to reduce the color palette</param>
        /// <param name="maxColors">The maximum number of colors to reduce the palette to</param>
        public QuantizeProcessor(IQuantizer <TPixel> quantizer, int maxColors)
        {
            Guard.NotNull(quantizer, nameof(quantizer));
            Guard.MustBeGreaterThan(maxColors, 0, nameof(maxColors));

            this.Quantizer = quantizer;
            this.MaxColors = maxColors;
        }
Пример #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FrameQuantizerBase{TPixel}"/> class.
        /// </summary>
        /// <param name="quantizer">The quantizer</param>
        /// <param name="singlePass">
        /// If true, the quantization process only needs to loop through the source pixels once
        /// </param>
        /// <remarks>
        /// If you construct this class with a <value>true</value> for <paramref name="singlePass"/>, then the code will
        /// only call the <see cref="SecondPass(ImageFrame{TPixel}, Span{byte}, ReadOnlySpan{TPixel},  int, int)"/> method.
        /// If two passes are required, the code will also call <see cref="FirstPass(ImageFrame{TPixel}, int, int)"/>.
        /// </remarks>
        protected FrameQuantizerBase(IQuantizer quantizer, bool singlePass)
        {
            Guard.NotNull(quantizer, nameof(quantizer));

            this.Diffuser   = quantizer.Diffuser;
            this.Dither     = this.Diffuser != null;
            this.singlePass = singlePass;
        }
Пример #18
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="Image{TColor, TPacked}"/>.
        /// </summary>
        /// <typeparam name="TColor">The pixel format.</typeparam>
        /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
        /// <param name="image">The <see cref="Image{TColor, TPacked}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TColor, TPacked>(Image <TColor, TPacked> image, Stream stream)
            where TColor : struct, IPackedPixel <TPacked>
            where TPacked : struct
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            if (this.Quantizer == null)
            {
                this.Quantizer = new OctreeQuantizer <TColor, TPacked>();
            }

            // Do not use IDisposable pattern here as we want to preserve the stream.
            EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream);

            // Ensure that quality can be set but has a fallback.
            int quality = this.Quality > 0 ? this.Quality : image.Quality;

            this.Quality = quality > 0 ? quality.Clamp(1, 256) : 256;

            // Get the number of bits.
            this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(this.Quality);

            // Quantize the image returning a palette.
            QuantizedImage <TColor, TPacked> quantized = ((IQuantizer <TColor, TPacked>) this.Quantizer).Quantize(image, this.Quality);

            int index = GetTransparentIndex(quantized);

            // Write the header.
            this.WriteHeader(writer);

            // Write the LSD. We'll use local color tables for now.
            this.WriteLogicalScreenDescriptor(image, writer, index);

            // Write the first frame.
            this.WriteGraphicalControlExtension(image, writer, index);
            this.WriteImageDescriptor(image, writer);
            this.WriteColorTable(quantized, writer);
            this.WriteImageData(quantized, writer);

            // Write additional frames.
            if (image.Frames.Any())
            {
                this.WriteApplicationExtension(writer, image.RepeatCount, image.Frames.Count);
                foreach (ImageFrame <TColor, TPacked> frame in image.Frames)
                {
                    QuantizedImage <TColor, TPacked> quantizedFrame = ((IQuantizer <TColor, TPacked>) this.Quantizer).Quantize(frame, this.Quality);

                    this.WriteGraphicalControlExtension(frame, writer, GetTransparentIndex(quantizedFrame));
                    this.WriteImageDescriptor(frame, writer);
                    this.WriteColorTable(quantizedFrame, writer);
                    this.WriteImageData(quantizedFrame, writer);
                }
            }

            // TODO: Write Comments extension etc
            writer.Write(GifConstants.EndIntroducer);
        }
Пример #19
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="Image{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        public void Encode <TPixel>(Image <TPixel> image, Stream stream)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            this.Quantizer = this.options.Quantizer ?? new OctreeQuantizer <TPixel>();

            // Do not use IDisposable pattern here as we want to preserve the stream.
            EndianBinaryWriter writer = new EndianBinaryWriter(Endianness.LittleEndian, stream);

            // Ensure that quality can be set but has a fallback.
            int quality = this.options.Quality > 0 ? this.options.Quality : image.MetaData.Quality;

            quality = quality > 0 ? quality.Clamp(1, 256) : 256;

            // Get the number of bits.
            this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(quality);

            // Quantize the image returning a palette.
            QuantizedImage <TPixel> quantized = ((IQuantizer <TPixel>) this.Quantizer).Quantize(image, quality);

            int index = this.GetTransparentIndex(quantized);

            // Write the header.
            this.WriteHeader(writer);

            // Write the LSD. We'll use local color tables for now.
            this.WriteLogicalScreenDescriptor(image, writer, index);

            // Write the first frame.
            this.WriteGraphicalControlExtension(image, writer, index);
            this.WriteComments(image, writer);
            this.WriteImageDescriptor(image, writer);
            this.WriteColorTable(quantized, writer);
            this.WriteImageData(quantized, writer);

            // Write additional frames.
            if (image.Frames.Any())
            {
                this.WriteApplicationExtension(writer, image.MetaData.RepeatCount, image.Frames.Count);

                // ReSharper disable once ForCanBeConvertedToForeach
                for (int i = 0; i < image.Frames.Count; i++)
                {
                    ImageFrame <TPixel>     frame          = image.Frames[i];
                    QuantizedImage <TPixel> quantizedFrame = ((IQuantizer <TPixel>) this.Quantizer).Quantize(frame, quality);

                    this.WriteGraphicalControlExtension(frame, writer, this.GetTransparentIndex(quantizedFrame));
                    this.WriteImageDescriptor(frame, writer);
                    this.WriteColorTable(quantizedFrame, writer);
                    this.WriteImageData(quantizedFrame, writer);
                }
            }

            // TODO: Write extension etc
            writer.Write(GifConstants.EndIntroducer);
        }
Пример #20
0
        public void Encode(ImageBase imageBase, Stream stream)
        {
            if (imageBase == null || stream == null)
            {
                throw new ArgumentNullException();
            }
            Image2 image = (Image2)imageBase;

            if (Quantizer == null)
            {
                Quantizer = new OctreeQuantizer {
                    Threshold = Threshold
                };
            }

            // Do not use IDisposable pattern here as we want to preserve the stream.
            EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream);

            // Ensure that quality can be set but has a fallback.
            int quality = Quality > 0 ? Quality : imageBase.Quality;

            Quality = quality > 0 ? NumUtils.Clamp(quality, 1, 256) : 256;

            // Get the number of bits.
            bitDepth = GetBitsNeededForColorDepth(Quality);

            // Quantize the image returning a palette.
            QuantizedImage quantized = Quantizer.Quantize(image, Quality);

            // Write the header.
            WriteHeader(writer);

            // Write the LSD. We'll use local color tables for now.
            WriteLogicalScreenDescriptor(image, writer, quantized.TransparentIndex);

            // Write the first frame.
            WriteGraphicalControlExtension(imageBase, writer, quantized.TransparentIndex);
            WriteImageDescriptor(image, writer);
            WriteColorTable(quantized, writer);
            WriteImageData(quantized, writer);

            // Write additional frames.
            if (image.Frames.Any())
            {
                WriteApplicationExtension(writer, image.RepeatCount, image.Frames.Count);
                foreach (ImageFrame frame in image.Frames)
                {
                    QuantizedImage quantizedFrame = Quantizer.Quantize(frame, Quality);
                    WriteGraphicalControlExtension(frame, writer, quantizedFrame.TransparentIndex);
                    WriteImageDescriptor(frame, writer);
                    WriteColorTable(quantizedFrame, writer);
                    WriteImageData(quantizedFrame, writer);
                }
            }

            // TODO: Write Comments extension etc
            writer.Write(GifConstants.endIntroducer);
        }
Пример #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FrameQuantizer{TPixel}"/> class.
        /// </summary>
        /// <param name="configuration">The configuration which allows altering default behaviour or extending the library.</param>
        /// <param name="quantizer">The quantizer</param>
        /// <param name="singlePass">
        /// If true, the quantization process only needs to loop through the source pixels once
        /// </param>
        /// <remarks>
        /// If you construct this class with a <value>true</value> for <paramref name="singlePass"/>, then the code will
        /// only call the <see cref="SecondPass(ImageFrame{TPixel}, Span{byte}, ReadOnlySpan{TPixel},  int, int)"/> method.
        /// If two passes are required, the code will also call <see cref="FirstPass(ImageFrame{TPixel}, int, int)"/>.
        /// </remarks>
        protected FrameQuantizer(Configuration configuration, IQuantizer quantizer, bool singlePass)
        {
            Guard.NotNull(quantizer, nameof(quantizer));

            this.Configuration = configuration;
            this.Diffuser      = quantizer.Diffuser;
            this.Dither        = this.Diffuser != null;
            this.singlePass    = singlePass;
        }
Пример #22
0
        protected BaseEngine(ICamera camera, IClock clock, IExecutor executor, IQuantizer quantizer, IAgent agent)
        {
            Camera    = camera;
            Clock     = clock;
            Executor  = executor;
            Quantizer = quantizer;

            Agent = agent;
        }
Пример #23
0
        /// <summary>
        /// Applies quantization to the image.
        /// </summary>
        /// <typeparam name="T">The pixel format.</typeparam>
        /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
        /// <param name="source">The image this method extends.</param>
        /// <param name="quantizer">The quantizer to apply to perform the operation.</param>
        /// <param name="maxColors">The maximum number of colors to return.</param>
        /// <returns>The <see cref="Image{T,TP}"/>.</returns>
        public static Image <T, TP> Quantize <T, TP>(this Image <T, TP> source, IQuantizer <T, TP> quantizer, int maxColors)
            where T : IPackedVector <TP>
            where TP : struct
        {
            QuantizedImage <T, TP> quantizedImage = quantizer.Quantize(source, maxColors);

            source.SetPixels(source.Width, source.Height, quantizedImage.ToImage().Pixels);
            return(source);
        }
Пример #24
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GifEncoderCore"/> class.
        /// </summary>
        /// <param name="options">The options for the encoder.</param>
        public GifEncoderCore(IGifEncoderOptions options)
        {
            this.textEncoding = options.TextEncoding ?? GifConstants.DefaultEncoding;

            this.quantizer      = options.Quantizer;
            this.threshold      = options.Threshold;
            this.paletteSize    = options.PaletteSize;
            this.ignoreMetadata = options.IgnoreMetadata;
        }
Пример #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PngEncoderCore"/> class.
 /// </summary>
 /// <param name="memoryManager">The <see cref="MemoryManager"/> to use for buffer allocations.</param>
 /// <param name="options">The options for influencing the encoder</param>
 public PngEncoderCore(MemoryManager memoryManager, IPngEncoderOptions options)
 {
     this.memoryManager    = memoryManager;
     this.pngColorType     = options.PngColorType;
     this.compressionLevel = options.CompressionLevel;
     this.gamma            = options.Gamma;
     this.quantizer        = options.Quantizer;
     this.threshold        = options.Threshold;
     this.writeGamma       = options.WriteGamma;
 }
Пример #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PngEncoderCore"/> class.
 /// </summary>
 /// <param name="memoryAllocator">The <see cref="MemoryAllocator"/> to use for buffer allocations.</param>
 /// <param name="options">The options for influencing the encoder</param>
 public PngEncoderCore(MemoryAllocator memoryAllocator, IPngEncoderOptions options)
 {
     this.memoryAllocator  = memoryAllocator;
     this.pngBitDepth      = options.BitDepth;
     this.pngColorType     = options.ColorType;
     this.pngFilterMethod  = options.FilterMethod;
     this.compressionLevel = options.CompressionLevel;
     this.gamma            = options.Gamma;
     this.quantizer        = options.Quantizer;
     this.threshold        = options.Threshold;
 }
Пример #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PngEncoderCore"/> class.
 /// </summary>
 /// <param name="options">The options for influencing the encoder</param>
 public PngEncoderCore(IPngEncoderOptions options)
 {
     this.ignoreMetadata   = options.IgnoreMetadata;
     this.paletteSize      = options.PaletteSize > 0 ? options.PaletteSize.Clamp(1, int.MaxValue) : int.MaxValue;
     this.pngColorType     = options.PngColorType;
     this.compressionLevel = options.CompressionLevel;
     this.gamma            = options.Gamma;
     this.quantizer        = options.Quantizer;
     this.threshold        = options.Threshold;
     this.writeGamma       = options.WriteGamma;
 }
Пример #28
0
        public void QuantizeImageShouldPreserveMaximumColorPrecision <TPixel>(TestImageProvider <TPixel> provider, string quantizerName)
            where TPixel : struct, IPixel <TPixel>
        {
            provider.Configuration.MemoryManager = ArrayPoolMemoryManager.CreateWithModeratePooling();

            IQuantizer quantizer = GetQuantizer(quantizerName);

            using (Image <TPixel> image = provider.GetImage())
            {
                image.Mutate(c => c.Quantize(quantizer));
                image.DebugSave(provider, new PngEncoder()
                {
                    PngColorType = PngColorType.Palette
                }, testOutputDetails: quantizerName);
            }

            provider.Configuration.MemoryManager.ReleaseRetainedResources();

            //string path = TestEnvironment.CreateOutputDirectory("Quantize");

            //foreach (TestFile file in Files)
            //{
            //    using (Image<Rgba32> srcImage = Image.Load<Rgba32>(file.Bytes, out IImageFormat mimeType))
            //    {
            //        using (Image<Rgba32> image = srcImage.Clone())
            //        {
            //            using (FileStream output = File.OpenWrite($"{path}/Octree-{file.FileName}"))
            //            {
            //                image.Mutate(x => x.Quantize(KnownQuantizers.Octree));
            //                image.Save(output, mimeType);
            //            }
            //        }

            //        using (Image<Rgba32> image = srcImage.Clone())
            //        {
            //            using (FileStream output = File.OpenWrite($"{path}/Wu-{file.FileName}"))
            //            {
            //                image.Mutate(x => x.Quantize(KnownQuantizers.Wu));
            //                image.Save(output, mimeType);
            //            }
            //        }

            //        using (Image<Rgba32> image = srcImage.Clone())
            //        {
            //            using (FileStream output = File.OpenWrite($"{path}/Palette-{file.FileName}"))
            //            {
            //                image.Mutate(x => x.Quantize(KnownQuantizers.Palette));
            //                image.Save(output, mimeType);
            //            }
            //        }
            //    }
            //}
        }
Пример #29
0
        public void SaveAsIconTest(PixelFormat pixelFormat)
        {
            var        ms        = new MemoryStream();
            IQuantizer quantizer = pixelFormat.IsIndexed() ? OptimizedPaletteQuantizer.Octree(1 << pixelFormat.ToBitsPerPixel()) : null;
            var        refImage  = Convert(Icons.Information.ExtractBitmap(new Size(64, 64)), pixelFormat, quantizer);

            refImage.SaveAsIcon(ms);
            ms.Position = 0;
            var bmp = new Bitmap(ms);

            Assert.AreEqual(ImageFormat.Icon, bmp.RawFormat);
            Assert.AreEqual(PixelFormat.Format32bppArgb, bmp.PixelFormat);
            SaveImage($"{pixelFormat}", bmp, true);
        }
Пример #30
0
        public void SaveAsTiffTest(PixelFormat pixelFormat, PixelFormat savedFormat, PixelFormat?savedFormatLinux = null)
        {
            var        ms        = new MemoryStream();
            IQuantizer quantizer = pixelFormat.IsIndexed() ? OptimizedPaletteQuantizer.Octree(1 << pixelFormat.ToBitsPerPixel(), Color.Silver, 0) : null;
            var        refImage  = Convert(Icons.Information.ExtractBitmap(new Size(256, 256)), pixelFormat, quantizer);

            refImage.SaveAsTiff(ms);
            ms.Position = 0;
            var bmp = new Bitmap(ms);

            Assert.AreEqual(ImageFormat.Tiff, bmp.RawFormat);
            Assert.AreEqual(OSUtils.IsWindows ? savedFormat : savedFormatLinux ?? savedFormat, bmp.PixelFormat);
            SaveImage($"{pixelFormat}", bmp, true);
        }
Пример #31
0
 public static Image2 Quantize(this Image2 source, IQuantizer quantizer, int maxColors)
 {
     QuantizedImage quantizedImage = quantizer.Quantize(source, maxColors);
     source.SetPixels(source.Width, source.Height, quantizedImage.ToImage().Pixels);
     return source;
 }