public IEnumerable<MouseDragAction> GetDrawInstructions(List<ColorSpot> color, IDictionary<string, string> settings = null, IBrushChanger brushChanger = null)
{
List<ColorSpot> knownColors = color.ToList();
int ignoredColor;
try
{
ignoredColor = knownColors.IndexOf(knownColors.First(x => x.IsBackgroundColor));
}
catch (Exception)
{
throw new Exception("I need a background color!!");
}
// prevent drawing of single pixels etc
int colorGroupMinSize = settings.GetIntValueOrDefault("MinimumStrokeSize", 15);
var output = new List<MouseDragAction>();
using (var bitmap = new Bitmap(this._bitmapPath))
{
this._bitmapHeight = bitmap.Height;
this._bitmapWidth = bitmap.Width;
var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
this._colors = new int[bitmap.Width,bitmap.Height];
this._colorsProcessed = new bool[bitmap.Width,bitmap.Height];
//_pixels = new KeyValuePair<Point, PixelMeta>[bitmap.Width * bitmap.Height];
BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bitmap.Height;
var rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
int position = (y * bmpData.Stride) + (x * 3);
int blue = rgbValues[position];
int green = rgbValues[position + 1];
int red = rgbValues[position + 2];
Color currentColor = Color.FromArgb(red, green, blue);
ColorSpot closestColor = knownColors.OrderBy(c => c.Color.DifferenceTo(currentColor)).FirstOrDefault();
this._colors[x, y] = knownColors.IndexOf(closestColor);
}
}
bitmap.UnlockBits(bmpData);
}
var colorGroups = new List<List<Point>>();
for (int x = 0; x < this._bitmapWidth; x++)
{
for (int y = 0; y < this._bitmapHeight; y++)
{
if (this._colors[x, y] != ignoredColor && !this._colorsProcessed[x, y])
{
colorGroups.AddRange(this.GetNeighboringColors(x, y));
}
}
}
int? lastColorIndex = null;
IOrderedEnumerable<List<Point>> colorGroupsOrderedByColor =
colorGroups.Where(x => x.Count >= colorGroupMinSize).OrderBy(x => this._colors[x.First().X, x.First().Y]);
foreach (var colorGroup in colorGroupsOrderedByColor)
{
var colorOutput = new List<MouseDragAction>();
int currentColorIndex = this._colors[colorGroup.First().X, colorGroup.First().Y];
if (!lastColorIndex.HasValue || lastColorIndex.Value != currentColorIndex)
{
lastColorIndex = currentColorIndex;
ColorSpot currentColor = knownColors[this._colors[colorGroup.First().X, colorGroup.First().Y]];
var colorChangeAction = new MouseDragAction(new List<Point> { currentColor.Point }, true, currentColor.Color);
colorOutput.Add(colorChangeAction);
}
var ma = new MouseDragAction(colorGroup.Select(x => new Point(x.X, x.Y)).ToList());
colorOutput.Add(ma);
output.AddRange(colorOutput);
}
return output;
}