#region License Information (GPL v3) /* ShareX - A program that allows you to take screenshots and share any file type Copyright (c) 2007-2024 ShareX Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Optionally you can also view the license at . */ #endregion License Information (GPL v3) using System.Collections; using System.Drawing; using System.Drawing.Imaging; namespace ShareX.HelpersLib { /// /// Summary description for PaletteQuantizer. /// public class PaletteQuantizer : Quantizer { /// /// Construct the palette quantizer /// /// The color palette to quantize to /// /// Palette quantization only requires a single quantization step /// public PaletteQuantizer(ArrayList palette) : base(true) { _colorMap = new Hashtable(); _colors = new Color[palette.Count]; palette.CopyTo(_colors); } /// /// Override this to process the pixel in the second pass of the algorithm /// /// The pixel to quantize /// The quantized value protected override byte QuantizePixel(Color32 pixel) { byte colorIndex = 0; int colorHash = pixel.ARGB; // Check if the color is in the lookup table if (_colorMap.ContainsKey(colorHash)) { colorIndex = (byte)_colorMap[colorHash]; } else { // Not found - loop through the palette and find the nearest match. // Firstly check the alpha value - if 0, lookup the transparent color if (pixel.Alpha == 0) { // Transparent. Lookup the first color with an alpha value of 0 for (int index = 0; index < _colors.Length; index++) { if (_colors[index].A == 0) { colorIndex = (byte)index; break; } } } else { // Not transparent... int leastDistance = int.MaxValue; int red = pixel.Red; int green = pixel.Green; int blue = pixel.Blue; // Loop through the entire palette, looking for the closest color match for (int index = 0; index < _colors.Length; index++) { Color paletteColor = _colors[index]; int redDistance = paletteColor.R - red; int greenDistance = paletteColor.G - green; int blueDistance = paletteColor.B - blue; int distance = (redDistance * redDistance) + (greenDistance * greenDistance) + (blueDistance * blueDistance); if (distance < leastDistance) { colorIndex = (byte)index; leastDistance = distance; // And if it's an exact match, exit the loop if (distance == 0) { break; } } } } // Now I have the color, pop it into the hashtable for next time _colorMap.Add(colorHash, colorIndex); } return colorIndex; } /// /// Retrieve the palette for the quantized image /// /// Any old palette, this is overrwritten /// The new color palette protected override ColorPalette GetPalette(ColorPalette palette) { for (int index = 0; index < _colors.Length; index++) { palette.Entries[index] = _colors[index]; } return palette; } /// /// Lookup table for colors /// private Hashtable _colorMap; /// /// List of all colors in the palette /// protected Color[] _colors; } }