// --------------------------------------------------------------------------------------------------------------------
//
// 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;
}
}
}
}