private byte[] IndexPixels(List <Color> palette) { return(NonIndexedPixels.AsParallel().Select((x, i) => new { Index = i, Indexed = (byte)ColorExtensions.ClosestColorRgb(palette, x) }).Select(x => x.Indexed).ToArray()); #region Old code //var pixels = new byte[NonIndexedPixels.Count]; //var pixelCount = 0; //foreach (var color in NonIndexedPixels) //{ // var index = palette.IndexOf(color); // if (index == -1) // { // //Search for nearby colors. // index = ColorExtensions.ClosestColorRgb(palette, color); // //index = ColorExtensions.ClosestColorHue(palette, color); // //index = ColorExtensions.ClosestColorRsb(palette, color); // //Add colors to a dictionary, if available, no need to search. // //TODO: Make this available for choice. // } // //Map the pixel to a color in the Color Table. // pixels[pixelCount] = (byte)index; // pixelCount++; //} //return pixels; #endregion }
private void GeneratePalette() { //TODO: more ways to decide which color to get //Like removing similar colors (with less than 5% similarity) if there is more than 256 colors, etc. //I probably can do that, using the groupby method. ColorTable = NonIndexedPixels.AsParallel().GroupBy(x => x) .OrderByDescending(g => g.Count()) //Order by most frequent values .Select(g => g.FirstOrDefault()) //take the first among the group .Take(MaximumNumberColor).ToList(); #region Handle transparency //Make sure that the transparent color is added to list. if (TransparentColor.HasValue && (!IsFirstFrame || UseGlobalColorTable) && ColorTable.Count == MaximumNumberColor) { //Only adds if there is MaximumNumberColor colors, so I need to make sure that the color won't be ignored. //If there is less than MaximumNumberColor selected colors, it means that the transparent color is already selected. //If the color isn't on the list, add or replace. if (ColorTable.AsParallel().All(x => x != TransparentColor.Value)) { //Adds to the last spot, keeping it sorted. (Since all the colors are ordered by descending) ColorTable.Insert(MaximumNumberColor - 1, TransparentColor.Value); //Remove the exceding value at the last position. ColorTable.RemoveAt(MaximumNumberColor); } } //I need to signal the other method that I won't need transparency. WillUseTransparency = !IsFirstFrame && TransparentColor.HasValue && ColorTable.Contains(TransparentColor.Value); #endregion }