public static (IEnumerable <int> indeces, IList <Color> palette) Quantize(Bitmap image, QuantizeImageSettings settings) { Setup(image, settings); var colors = Decompose(image); var indices = settings.Ditherer?.Process(colors) ?? settings.Quantizer.Process(colors); return(indices, settings.Quantizer.GetPalette()); }
private void ReadPixels(byte[] pixels) { if (QuantizationType == ColorQuantizationType.Neural) { #region Neural if (GlobalQuantizer == null || !UseGlobalColorTable) { GlobalQuantizer = new NeuralQuantizer(SamplingFactor, MaximumNumberColor) { MaxColors = MaximumNumberColor, TransparentColor = !IsFirstFrame || UseGlobalColorTable || UseFullTransparency ? TransparentColor : null }; GlobalQuantizer.FirstPass(pixels); ColorTable = GlobalQuantizer.GetPalette(); } //Indexes the pixels to the color table. IndexedPixels = GlobalQuantizer.SecondPass(pixels); #endregion } else if (QuantizationType == ColorQuantizationType.Octree) { #region Octree var quantizer = new OctreeQuantizer { MaxColors = MaximumNumberColor, TransparentColor = !IsFirstFrame || UseGlobalColorTable || UseFullTransparency ? TransparentColor : null }; IndexedPixels = quantizer.Quantize(pixels); ColorTable = quantizer.ColorTable; #endregion } else if (QuantizationType == ColorQuantizationType.MedianCut) { #region Median cut if (GlobalQuantizer == null || !UseGlobalColorTable) { GlobalQuantizer = new MedianCutQuantizer { MaxColors = MaximumNumberColor, TransparentColor = !IsFirstFrame || UseGlobalColorTable || UseFullTransparency ? TransparentColor : null }; GlobalQuantizer.FirstPass(pixels); ColorTable = GlobalQuantizer.GetPalette(); } //Indexes the pixels to the color table. IndexedPixels = GlobalQuantizer.SecondPass(pixels); #endregion } else if (QuantizationType == ColorQuantizationType.Grayscale) { #region Grayscale //This quantizer uses a fixed palette (generated during object instantiation), so most calculations are called one time. if (GlobalQuantizer == null) { //Since the color table does not change among frames, it can be stored globally. UseGlobalColorTable = true; var transparent = !IsFirstFrame || UseGlobalColorTable || UseFullTransparency ? TransparentColor : null; GlobalQuantizer = new GrayscaleQuantizer(transparent, MaximumNumberColor) { MaxColors = MaximumNumberColor, TransparentColor = transparent }; ColorTable = GlobalQuantizer.GetPalette(); } //Each frame still needs to be quantized. IndexedPixels = GlobalQuantizer.SecondPass(pixels); #endregion } else if (QuantizationType == ColorQuantizationType.MostUsed) { #region Most used colors if (GlobalQuantizer == null || !UseGlobalColorTable) { GlobalQuantizer = new MostUsedQuantizer { MaxColors = MaximumNumberColor, TransparentColor = !IsFirstFrame || UseGlobalColorTable || UseFullTransparency ? TransparentColor : null }; GlobalQuantizer.FirstPass(pixels); ColorTable = GlobalQuantizer.GetPalette(); } //Indexes the pixels to the color table. IndexedPixels = GlobalQuantizer.SecondPass(pixels); #endregion } else { #region Palette //This quantizer uses a fixed palette (generated during object instantiation), so it will be only called once. if (GlobalQuantizer == null) { //Since the color table does not change among frames, it can be stored globally. UseGlobalColorTable = true; var transparent = !IsFirstFrame || UseGlobalColorTable || UseFullTransparency ? TransparentColor : null; //TODO: Pass the palette. //Default palettes: Windows, etc. //User submitted > Presets > Generate palette based on first frame. GlobalQuantizer = new PaletteQuantizer(new ArrayList()) { MaxColors = MaximumNumberColor, TransparentColor = transparent }; ColorTable = GlobalQuantizer.GetPalette(); } //Each frame still needs to be quantized. IndexedPixels = GlobalQuantizer.SecondPass(pixels); #endregion } //I need to signal the other method that I'll need transparency. ColorTableHasTransparency = TransparentColor.HasValue && ColorTable.Contains(TransparentColor.Value); }