diff --git a/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs b/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs index b3d5527..11e47e1 100644 --- a/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs +++ b/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs @@ -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) diff --git a/OSCADSharp/OSCADSharp/Utility/Images/ImageSimplifier.cs b/OSCADSharp/OSCADSharp/Utility/Images/ImageSimplifier.cs index 08402a9..7bfd348 100644 --- a/OSCADSharp/OSCADSharp/Utility/Images/ImageSimplifier.cs +++ b/OSCADSharp/OSCADSharp/Utility/Images/ImageSimplifier.cs @@ -20,6 +20,69 @@ namespace OSCADSharp.Utility.Images this.pixels = pixels; } + /// + /// 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 + /// + /// + 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)