Example #1
0
        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;
        }