diff --git a/OSCADSharp/OSCADSharp/Solids/Imported/ImageImportOptions.cs b/OSCADSharp/OSCADSharp/Solids/Imported/ImageImportOptions.cs
index 97a8809..83f5357 100644
--- a/OSCADSharp/OSCADSharp/Solids/Imported/ImageImportOptions.cs
+++ b/OSCADSharp/OSCADSharp/Solids/Imported/ImageImportOptions.cs
@@ -20,5 +20,10 @@ namespace OSCADSharp.Solids.Imported
/// Converts the colors in the image to black and white
///
public bool UseGrayScale { get; set; } = false;
+
+ ///
+ /// Reduces the total number of colors in the image by merging similar colors together.
+ ///
+ public byte SimplificationAmount { get; set; } = 0;
}
}
diff --git a/OSCADSharp/OSCADSharp/Solids/Imported/ImportedImage.cs b/OSCADSharp/OSCADSharp/Solids/Imported/ImportedImage.cs
index 8302590..d13a0d0 100644
--- a/OSCADSharp/OSCADSharp/Solids/Imported/ImportedImage.cs
+++ b/OSCADSharp/OSCADSharp/Solids/Imported/ImportedImage.cs
@@ -35,7 +35,7 @@ namespace OSCADSharp.Solids.Imported
options = new ImageImportOptions();
}
- processor = new CubistImageProcessor(imagePath, options.HeightMapping, options.UseGrayScale);
+ processor = new CubistImageProcessor(imagePath, options.HeightMapping, options.UseGrayScale, options.SimplificationAmount);
var obj = processor.ProcessImage();
var img = new ImportedImage()
diff --git a/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs b/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs
index dd2e968..f7c7977 100644
--- a/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs
+++ b/OSCADSharp/OSCADSharp/Utility/Images/CubistImageProcessor.cs
@@ -22,17 +22,19 @@ namespace OSCADSharp.Utility.Images
List cubes = new List();
private Color[,] pixels;
private bool useGrayScale;
+ private byte simplificationAmount;
#endregion
#region Internal Fields
public Bounds ImageBounds { get; set; }
#endregion
- internal CubistImageProcessor(string imagePath, bool includeHeight = true, bool useGrayScale = false)
+ internal CubistImageProcessor(string imagePath, bool includeHeight = true, bool useGrayScale = false, byte simplificationAmount = 0)
{
this.includeHeight = includeHeight;
this.imagePath = imagePath;
this.useGrayScale = useGrayScale;
+ this.simplificationAmount = simplificationAmount;
}
public OSCADObject ProcessImage()
@@ -47,6 +49,7 @@ namespace OSCADSharp.Utility.Images
{
Bitmap img = new Bitmap(Image.FromFile(this.imagePath));
this.setColorArray(img);
+ this.simlifyColors(img);
this.setHeightMappings(img);
this.ImageBounds = new Bounds(new Vector3(), new Vector3(img.Width, img.Height, 1));
@@ -82,6 +85,56 @@ namespace OSCADSharp.Utility.Images
return cubes;
}
+ private void simlifyColors(Bitmap img)
+ {
+ if (this.simplificationAmount == 0)
+ {
+ return;
+ }
+
+ // These calls color values from their originals to new ones based upon the color's proximity to the simpification amount
+ // the channelSelector and colorFactory functions allow us to use the same function for each.
+ // TODO: Refactor into a class
+ mapColors(img, (c) => { return c.R; }, (orig, retained) => { return Color.FromArgb(orig.A, retained.R, orig.G, orig.B); });
+ mapColors(img, (c) => { return c.G; }, (orig, retained) => { return Color.FromArgb(orig.A, orig.R, retained.G, orig.B); });
+ mapColors(img, (c) => { return c.B; }, (orig, retained) => { return Color.FromArgb(orig.A, orig.R, orig.G, retained.B); });
+ }
+
+ private void mapColors(Bitmap img, Func channelSelector, Func colorFactory)
+ {
+ Dictionary colorsRetained = new Dictionary();
+
+ for (int x = 0; x < img.Width; x++)
+ {
+ for (int y = 0; y < img.Height; y++)
+ {
+ Color curColor;
+ bool colorMatched = false;
+ curColor = this.pixels[x, y];
+ for (int simVal = 0; simVal < this.simplificationAmount; simVal++)
+ {
+ int upperLimit = channelSelector(curColor) + simVal;
+ int lowerLimit = channelSelector(curColor) - simVal;
+ if (upperLimit <= 255 && colorsRetained.ContainsKey((byte)upperLimit))
+ {
+ this.pixels[x, y] = colorFactory(curColor, colorsRetained[(byte)upperLimit]);
+ colorMatched = true;
+ }
+ else if (lowerLimit >= 0 && colorsRetained.ContainsKey((byte)lowerLimit))
+ {
+ this.pixels[x, y] = colorFactory(curColor, colorsRetained[(byte)lowerLimit]);
+ colorMatched = true;
+ }
+ }
+
+ if (!colorMatched)
+ {
+ colorsRetained[channelSelector(curColor)] = curColor;
+ }
+ }
+ }
+ }
+
private void setColorArray(Bitmap img)
{
this.pixels = new Color[img.Width, img.Height];