void DoRegionFillingByEdgeTracing(int* image, int x, int y, int image_width, int image_height, int filling_colour) { int index_cen = y * image_width + x; int index[8]; index[0] = std::max(y - 1, 0) * image_width + std::min(x + 1, image_width); index[1] = std::max(y - 1, 0) * image_width + x; index[2] = std::max(y - 1, 0) * image_width + std::max(x - 1, 0); index[3] = y * image_width + std::max(x - 1, 0); index[4] = y * image_width + std::min(x + 1, image_width); index[5] = std::min(y + 1, image_height) * image_width + std::min(x + 1, image_width); index[6] = std::min(y + 1, image_height) * image_width + x; index[7] = std::min(y + 1, image_height) * image_width + std::max(x - 1, 0); int firstPoint = 0; if (image[index_cen] == WHITE) { firstPoint = index_cen; int previous_index_cen = 0; int next_index_cen = 0; for (int i = 0; i < 8; i++) { if (image[index[i]] == WHITE) { previous_index_cen = index[i]; break; } } std::vector<int> start_points; std::vector<int> end_points; int delt_angle = 0; int clockwise = 0; int* tmp_array = new int[image_width * image_height]; while (previous_index_cen != 0) { int findPoint = FindNextPoint(image, previous_index_cen, index_cen, image_width, &next_index_cen, &delt_angle); if (findPoint == 1) { if (index_cen == firstPoint && image[next_index_cen] != WHITE) { Filling(image, start_points, end_points, clockwise, filling_colour); start_points.clear(); end_points.clear(); delt_angle = 0; delete [] tmp_array; return; } SetColourForPoints(image, tmp_array, previous_index_cen, index_cen, next_index_cen, image_width, &start_points, &end_points); } else { delete [] tmp_array; return; } previous_index_cen = index_cen; index_cen = next_index_cen; } delete [] tmp_array; } }
// **************************************************************************** // // Function Name: FollowOutline() // // Description: Follow the outline from a starting point in a DIB. // // Returns: TRUE if points added to Polygon, FALSE if not // // Exceptions: Memory exception // // **************************************************************************** static BOOLEAN FollowOutline (const RIntPoint& StartPoint, uBYTE InitialDirection, const DIBINFO& Dib, CPixelGrid& PixelGrid, RPolyPolygon& rPolyPoly) { uBYTE Direction, PreviousDirection; RIntPoint LastPoint, NextPoint; if (PixelGrid.IsPointDirty (StartPoint)) { // This point has already been used return FALSE; } Direction = InitialDirection; PreviousDirection = NULL_DIRECTION; LastPoint = StartPoint; rPolyPoly.NewPolygon(); do { Direction = FindNextPoint (LastPoint, NextPoint, Direction, Dib); if (Direction == NULL_DIRECTION) { // There is only one pixel in this shape rPolyPoly.AddPoint (LastPoint); } else if (Direction != PreviousDirection) { rPolyPoly.AddPoint (LastPoint); } PreviousDirection = Direction; // Adjust direction if (Direction & 0x01) { // Direction is odd Direction = (uBYTE)((Direction + 2) & 0x07); } else { // Direction is even Direction = (uBYTE)((Direction + 1) & 0x07); } LastPoint = NextPoint; // Must add all points traversed to pixel grid so they are not // considered as part of another shape PixelGrid.MarkPoint (LastPoint); } while ( LastPoint != StartPoint ); // Make sure that start point is also end point of polyline rPolyPoly.AddPoint (LastPoint); // Notify class this polygon is done rPolyPoly.EndPolygon(); return TRUE; }