/// <inheritdoc/> public virtual QuantizedFrame <TPixel> QuantizeFrame(ImageFrame <TPixel> image) { Guard.NotNull(image, nameof(image)); // Get the size of the source image int height = image.Height; int width = image.Width; // Call the FirstPass function if not a single pass algorithm. // For something like an Octree quantizer, this will run through // all image pixels, build a data structure, and create a palette. if (!this.singlePass) { this.FirstPass(image, width, height); } // Collect the palette. Required before the second pass runs. TPixel[] palette = this.GetPalette(); this.paletteVector = new Vector4[palette.Length]; PixelOperations <TPixel> .Instance.ToVector4(image.Configuration, (ReadOnlySpan <TPixel>) palette, (Span <Vector4>) this.paletteVector, PixelConversionModifiers.Scale); var quantizedFrame = new QuantizedFrame <TPixel>(image.MemoryAllocator, width, height, palette); if (this.Dither) { // We clone the image as we don't want to alter the original via dithering. using (ImageFrame <TPixel> clone = image.Clone()) { this.SecondPass(clone, quantizedFrame.GetPixelSpan(), palette, width, height); } } else { this.SecondPass(image, quantizedFrame.GetPixelSpan(), palette, width, height); } return(quantizedFrame); }
/// <inheritdoc /> protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration) { using (IFrameQuantizer <TPixel> executor = this.quantizer.CreateFrameQuantizer <TPixel>(configuration)) using (QuantizedFrame <TPixel> quantized = executor.QuantizeFrame(source)) { int paletteCount = quantized.Palette.Length - 1; // Not parallel to remove "quantized" closure allocation. // We can operate directly on the source here as we've already read it to get the // quantized result for (int y = 0; y < source.Height; y++) { Span <TPixel> row = source.GetPixelRowSpan(y); ReadOnlySpan <byte> quantizedPixelSpan = quantized.GetPixelSpan(); int yy = y * source.Width; for (int x = 0; x < source.Width; x++) { int i = x + yy; row[x] = quantized.Palette[Math.Min(paletteCount, quantizedPixelSpan[i])]; } } } }