// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // Encapsulates methods to calculate the color palette of an image using // a Wu color quantizer . // Adapted from // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Imaging.Quantizers.WuQuantizer { using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using ImageProcessor.Imaging.Colors; /// /// Encapsulates methods to calculate the color palette of an image using /// a Wu color quantizer . /// Adapted from /// public class WuQuantizer : WuQuantizerBase { /// /// Quantizes the image contained within the returning the result. /// /// /// The for storing and manipulating pixel information.. /// /// /// The maximum number of colors apply to the image. /// /// /// The array of containing indexed versions of the images colors. /// /// /// All colors with an alpha value less than this will be considered fully transparent. /// /// /// The quantized . /// internal override Bitmap GetQuantizedImage(ImageBuffer imageBuffer, int colorCount, Color32[] lookups, int alphaThreshold) { Bitmap result = new Bitmap(imageBuffer.Image.Width, imageBuffer.Image.Height, PixelFormat.Format8bppIndexed); result.SetResolution(imageBuffer.Image.HorizontalResolution, imageBuffer.Image.VerticalResolution); ImageBuffer resultBuffer = new ImageBuffer(result); PaletteColorHistory[] paletteHistogram = new PaletteColorHistory[colorCount + 1]; resultBuffer.UpdatePixelIndexes(IndexedPixels(imageBuffer, lookups, alphaThreshold, paletteHistogram)); result.Palette = BuildPalette(result.Palette, paletteHistogram); return result; } /// /// Builds a color palette from the given . /// /// /// The to fill. /// /// /// The containing the sum of all pixel data. /// /// /// The . /// private static ColorPalette BuildPalette(ColorPalette palette, PaletteColorHistory[] paletteHistory) { int length = paletteHistory.Length; for (int i = 0; i < length; i++) { palette.Entries[i] = paletteHistory[i].ToNormalizedColor(); } return palette; } /// /// Gets an enumerable array of bytes representing each row of the image. /// /// /// The for storing and manipulating pixel information. /// /// /// The array of containing indexed versions of the images colors. /// /// /// The alpha threshold. /// /// /// The palette histogram. /// /// /// The enumerable list of representing each pixel. /// private static IEnumerable IndexedPixels(ImageBuffer image, Color32[] lookups, int alphaThreshold, PaletteColorHistory[] paletteHistogram) { byte[] lineIndexes = new byte[image.Image.Width]; PaletteLookup lookup = new PaletteLookup(lookups); // Determine the correct fallback color. byte fallback = lookups.Length < AlphaMax ? AlphaMin : AlphaMax; foreach (Color32[] pixelLine in image.PixelLines) { int length = pixelLine.Length; for (int i = 0; i < length; i++) { Color32 pixel = pixelLine[i]; byte bestMatch = fallback; if (pixel.A > alphaThreshold) { bestMatch = lookup.GetPaletteIndex(pixel); paletteHistogram[bestMatch].AddPixel(pixel); } lineIndexes[i] = bestMatch; } yield return lineIndexes; } } } }