Implemented simple resampling algorithm to provide less hideous reduction of colors in processed images.

This commit is contained in:
Michael Smith 2016-05-16 23:41:40 -07:00
parent 8247c5b807
commit adc38a9742
2 changed files with 64 additions and 2 deletions

View File

@ -87,9 +87,8 @@ namespace OSCADSharp.Utility.Images
private void simplifyColors(Bitmap img)
{
var simplifier = new ImageSimplifier(img.Width, img.Height, pixels);
simplifier.GlobalReduction(this.simplificationAmount);
simplifier.BasicResample(this.simplificationAmount);
}
private void setColorArray(Bitmap img)

View File

@ -20,6 +20,69 @@ namespace OSCADSharp.Utility.Images
this.pixels = pixels;
}
/// <summary>
/// Partitions shades of red/green/blue into buckets and simplifies colors by
/// preserving only the most commonly occurring hues of each. SimplificationAmount determines
/// partition size.
///
/// Eg. s = 50, numPartitions = 255/50, approximately 5 shades of each hue
/// </summary>
/// <param name="simplificationAmount"></param>
internal void BasicResample(byte simplificationAmount)
{
if (simplificationAmount == 0)
{
return;
}
int[] reds = new int[256];
int[] greens = new int[256];
int[] blues = new int[256];
for (int x = 0; x < this.width; x++)
{
for (int y = 0; y < this.height; y++)
{
var pixel = pixels[x, y];
reds[pixel.R]++;
greens[pixel.G]++;
blues[pixel.B]++;
}
}
for (int x = 0; x < this.width; x++)
{
for (int y = 0; y < this.height; y++)
{
var pixel = pixels[x, y];
byte r = this.remapColor(reds, simplificationAmount, pixel.R);
byte g = this.remapColor(blues, simplificationAmount, pixel.G);
byte b = this.remapColor(greens, simplificationAmount, pixel.B);
pixels[x, y] = Color.FromArgb(pixel.A, r, g, b);
}
}
}
private byte remapColor(int[] hues, byte simplificationAmount, byte r)
{
int startIndex = (r / simplificationAmount) * simplificationAmount;
int maxVal = 0;
int indexOfMostCommonVal = startIndex;
for (int i = startIndex; i < startIndex + simplificationAmount && i < 256; i++)
{
if(hues[i] > maxVal)
{
maxVal = hues[i];
indexOfMostCommonVal = i;
}
}
return (byte)indexOfMostCommonVal;
}
internal void GlobalReduction(byte simplificationAmount)
{
if (simplificationAmount == 0)