|
|
@ -46,32 +46,35 @@ namespace ImageProcessor.Imaging.Quantizers.WuQuantizer |
|
|
var buffer = new ImageBuffer(image); |
|
|
var buffer = new ImageBuffer(image); |
|
|
|
|
|
|
|
|
if (histogram == null) |
|
|
if (histogram == null) |
|
|
|
|
|
{ |
|
|
histogram = new Histogram(); |
|
|
histogram = new Histogram(); |
|
|
|
|
|
} |
|
|
else |
|
|
else |
|
|
|
|
|
{ |
|
|
histogram.Clear(); |
|
|
histogram.Clear(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
BuildHistogram(histogram, buffer, alphaThreshold, alphaFader); |
|
|
BuildHistogram(histogram, buffer, alphaThreshold, alphaFader); |
|
|
CalculateMoments(histogram.Moments); |
|
|
CalculateMoments(histogram.Moments); |
|
|
var cubes = SplitData(ref maxColors, histogram.Moments); |
|
|
var cubes = SplitData(ref maxColors, histogram.Moments); |
|
|
var lookups = BuildLookups(cubes, histogram.Moments); |
|
|
var lookups = BuildLookups(cubes, histogram.Moments); |
|
|
return GetQuantizedImage(buffer, maxColors, lookups, alphaThreshold); |
|
|
return this.GetQuantizedImage(buffer, maxColors, lookups, alphaThreshold); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static void BuildHistogram(Histogram histogram, ImageBuffer sourceImage, int alphaThreshold, int alphaFader) |
|
|
private static void BuildHistogram(Histogram histogram, ImageBuffer sourceImage, int alphaThreshold, int alphaFader) |
|
|
{ |
|
|
{ |
|
|
var moments = histogram.Moments; |
|
|
ColorMoment[,,,] moments = histogram.Moments; |
|
|
|
|
|
|
|
|
foreach(var pixelLine in sourceImage.PixelLines) |
|
|
foreach (Pixel[] pixelLine in sourceImage.PixelLines) |
|
|
{ |
|
|
{ |
|
|
for (int pixelIndex = 0; pixelIndex < pixelLine.Length; pixelIndex++) |
|
|
foreach (Pixel pixel in pixelLine) |
|
|
{ |
|
|
{ |
|
|
Pixel pixel = pixelLine[pixelIndex]; |
|
|
|
|
|
byte pixelAlpha = pixel.Alpha; |
|
|
byte pixelAlpha = pixel.Alpha; |
|
|
if (pixelAlpha >= alphaThreshold) |
|
|
if (pixelAlpha >= alphaThreshold) |
|
|
{ |
|
|
{ |
|
|
if (pixelAlpha < 255) |
|
|
if (pixelAlpha < 255) |
|
|
{ |
|
|
{ |
|
|
var alpha = pixel.Alpha + (pixel.Alpha % alphaFader); |
|
|
int alpha = pixel.Alpha + (pixel.Alpha % alphaFader); |
|
|
pixelAlpha = (byte)(alpha > 255 ? 255 : alpha); |
|
|
pixelAlpha = (byte)(alpha > 255 ? 255 : alpha); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -91,17 +94,17 @@ namespace ImageProcessor.Imaging.Quantizers.WuQuantizer |
|
|
|
|
|
|
|
|
private static void CalculateMoments(ColorMoment[, , ,] moments) |
|
|
private static void CalculateMoments(ColorMoment[, , ,] moments) |
|
|
{ |
|
|
{ |
|
|
var xarea = new ColorMoment[SideSize, SideSize]; |
|
|
ColorMoment[,] xarea = new ColorMoment[SideSize, SideSize]; |
|
|
var area = new ColorMoment[SideSize]; |
|
|
ColorMoment[] area = new ColorMoment[SideSize]; |
|
|
for (var alphaIndex = 1; alphaIndex < SideSize; alphaIndex++) |
|
|
for (int alphaIndex = 1; alphaIndex < SideSize; alphaIndex++) |
|
|
{ |
|
|
{ |
|
|
for (var redIndex = 1; redIndex < SideSize; redIndex++) |
|
|
for (int redIndex = 1; redIndex < SideSize; redIndex++) |
|
|
{ |
|
|
{ |
|
|
Array.Clear(area, 0, area.Length); |
|
|
Array.Clear(area, 0, area.Length); |
|
|
for (var greenIndex = 1; greenIndex < SideSize; greenIndex++) |
|
|
for (int greenIndex = 1; greenIndex < SideSize; greenIndex++) |
|
|
{ |
|
|
{ |
|
|
var line = new ColorMoment(); |
|
|
ColorMoment line = new ColorMoment(); |
|
|
for (var blueIndex = 1; blueIndex < SideSize; blueIndex++) |
|
|
for (int blueIndex = 1; blueIndex < SideSize; blueIndex++) |
|
|
{ |
|
|
{ |
|
|
line.AddFast(ref moments[alphaIndex, redIndex, greenIndex, blueIndex]); |
|
|
line.AddFast(ref moments[alphaIndex, redIndex, greenIndex, blueIndex]); |
|
|
area[blueIndex].AddFast(ref line); |
|
|
area[blueIndex].AddFast(ref line); |
|
|
@ -220,10 +223,13 @@ namespace ImageProcessor.Imaging.Quantizers.WuQuantizer |
|
|
var result = 0.0f; |
|
|
var result = 0.0f; |
|
|
byte? cutPoint = null; |
|
|
byte? cutPoint = null; |
|
|
|
|
|
|
|
|
for (var position = first; position < last; ++position) |
|
|
for (byte position = first; position < last; ++position) |
|
|
|
|
|
{ |
|
|
|
|
|
ColorMoment half = bottom + Top(cube, direction, position, moments); |
|
|
|
|
|
if (half.Weight == 0) |
|
|
{ |
|
|
{ |
|
|
var half = bottom + Top(cube, direction, position, moments); |
|
|
continue; |
|
|
if (half.Weight == 0) continue; |
|
|
} |
|
|
|
|
|
|
|
|
var temp = half.WeightedDistance(); |
|
|
var temp = half.WeightedDistance(); |
|
|
|
|
|
|
|
|
|