/// <summary> /// Analyzes image colors and creates color map. /// </summary> private void AnalyzePixels() { int len = _pixels.Length; int nPix = len / 3; _indexedPixels = new byte[nPix]; //Initialize quantizer. var nq = new NeuQuant(_pixels, len, _sample); //Create reduced palette. _colorTab = nq.Process(); #region BGR to RGB for (int i = 0; i < _colorTab.Length; i += 3) { //Only swap Red with Blue. Green stays. byte temp = _colorTab[i]; _colorTab[i] = _colorTab[i + 2]; _colorTab[i + 2] = temp; _usedEntry[i / 3] = false; } #endregion //Map image pixels to new palette. int k = 0; _usedEntry = new bool[256]; for (int i = 0; i < nPix; i++) { int index = nq.Map( _pixels[k++], _pixels[k++], _pixels[k++]); _usedEntry[index] = true; _indexedPixels[i] = (byte)index; } _colorDepth = 8; _palSize = 7; //Get closest match to transparent color if specified. if (_transparent != Color.Empty) { _transIndex = nq.Map(_transparent.B, _transparent.G, _transparent.R); } _pixels = null; }
/// <summary> /// Analyzes image colors and creates color map. /// </summary> private void AnalyzePixels() { var len = _pixels.Length; var nPix = len / 3; _indexedPixels = new byte[nPix]; var colorTable = _colorList.GroupBy(x => x) //Grouping based on its value .OrderByDescending(g => g.Count()) //Order by most frequent values .Select(g => g.FirstOrDefault()) //take the first among the group .ToList(); //Could use .Take(256) _usedEntry = new bool[256]; if (colorTable.Count <= 256) { #region No quantitizer needed _colorTab = new byte[768]; int indexAux = 0; foreach (var color in colorTable) { _colorTab[indexAux++] = color.R; _colorTab[indexAux++] = color.G; _colorTab[indexAux++] = color.B; } //var grouped = _pixels.Select((x, i) => new { x, i }) // .GroupBy(x => x.i / 3) // .Select(g => g.ToList()) // .Select(g => new { R = g[0], G = g[1], B = g[2] }) // .Distinct(); var k = 0; for (var i = 0; i < nPix; i++) { var b = _pixels[k++]; var g = _pixels[k++]; var r = _pixels[k++]; var pos = colorTable.IndexOf(Color.FromArgb(r, g, b)); if (pos == -1 || pos > 255) { pos = 0; } _usedEntry[pos] = true; _indexedPixels[i] = (byte)pos; } //Get closest match to transparent color if specified. if (_transparent != Color.Empty) { _transIndex = colorTable.IndexOf(Color.FromArgb(_transparent.R, _transparent.G, _transparent.B)); if (_transIndex == -1) { _transIndex = 0; } } #endregion } else { #region Quantitizer needed //Neural quantitizer. var nq = new NeuQuant(_pixels, len, _sample); //Create reduced palette. _colorTab = nq.Process(); //Map image pixels to new palette. var k = 0; for (var i = 0; i < nPix; i++) { var index = nq.Map( _pixels[k++], _pixels[k++], _pixels[k++]); _usedEntry[index] = true; _indexedPixels[i] = (byte)index; } //Get closest match to transparent color if specified. if (_transparent != Color.Empty) { _transIndex = nq.Map(_transparent.B, _transparent.G, _transparent.R); } #endregion } _colorDepth = 8; _palSize = 7; _pixels = null; }