private void GenerateBordersPaths(Bitmap bitmap)
        {
            Rectangle  rect    = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            IntPtr     ptr     = bmpData.Scan0;
            int        bytes   = bmpData.Stride * bitmap.Height;

            byte[] rgbValues = new byte[bytes];
            Marshal.Copy(ptr, rgbValues, 0, bytes);
            int height = bitmap.Height;
            int width  = bitmap.Width;

            Color[,] pixelColors = new Color[bitmap.Height, bitmap.Width];
            // Store pixel color in matrix
            Parallel.For(0, bytes / 3, (int i) =>
            {
                i       *= 3;
                int pRow = (i / 3) / width;
                int pCol = (i / 3) % width;
                pixelColors[pRow, pCol] = Color.FromArgb(rgbValues[i + 2], rgbValues[i + 1], rgbValues[i]);
            });
            bitmap.UnlockBits(bmpData);
            // Stores vertical and horizontal border pixels of a province
            Dictionary <Color, HashSet <BorderPoint[]> > provincesPoints = new Dictionary <Color, HashSet <BorderPoint[]> >(this._mProvinceCount);

            object lockObj = new Object();

            //Traverse lines
            Parallel.For(0, height, (int prow) =>
            {
                for (int col = 0; col < width; col++)
                {
                    Color color = pixelColors[prow, col];
                    lock (lockObj)
                    {
                        if (!provincesPoints.ContainsKey(color))
                        {
                            provincesPoints.Add(color, new HashSet <BorderPoint[]>());
                        }
                    }
                    BorderPoint[] colorLine = new BorderPoint[3];
                    colorLine[0]            = new BorderPoint(col, prow);
                    do
                    {
                        if (col < width)
                        {
                            if (color == pixelColors[prow, col])
                            {
                                col++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    } while (true);
                    col--;
                    colorLine[1] = new BorderPoint(col, prow);
                    colorLine[2] = new BorderPoint(-1, 0); // horizontal line
                    lock (lockObj)
                    {
                        HashSet <BorderPoint[]> lines = provincesPoints[color];
                        lines.Add(colorLine);
                    }
                }
            });
            //Traverse columns
            Parallel.For(0, width, (int col) =>
            {
                for (int row = 0; row < height; row++)
                {
                    Color color             = pixelColors[row, col];
                    BorderPoint[] colorLine = new BorderPoint[3];
                    colorLine[0]            = new BorderPoint(col, row);
                    do
                    {
                        if (row < height)
                        {
                            if (color == pixelColors[row, col])
                            {
                                row++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    } while (true);
                    row--;
                    colorLine[1] = new BorderPoint(col, row);
                    colorLine[2] = new BorderPoint(-2, 0); // vertical line
                    lock (lockObj)
                    {
                        HashSet <BorderPoint[]> lines = provincesPoints[color];
                        lines.Add(colorLine);
                    }
                }
            });
            this._mProvincesLines = new Dictionary <Color, HashSet <BorderLine> >(provincesPoints.Count);
            // Get border lines from border pixels
            object lockobj = new Object();

            Parallel.ForEach(provincesPoints, (KeyValuePair <Color, HashSet <BorderPoint[]> > keyValue) =>
            {
                lock (lockobj)
                {
                    this._mProvincesLines.Add(keyValue.Key, new HashSet <BorderLine>(keyValue.Value.Count / 4));
                }
                this.ProcessProvince(keyValue.Value, this._mProvincesLines[keyValue.Key]);
            });
        }
Exemple #2
0
 /// <summary>
 /// Initialize a new instance of <see cref="BorderLine"/> that has the specified coordinates.
 /// </summary>
 /// <param name="start"> Start of the line.</param>
 /// <param name="end"> End of the line.</param>
 public BorderLine(BorderPoint start, BorderPoint end)
 {
     this._mStart = start;
     this._mEnd   = end;
 }