简体   繁体   中英

for loop is working for width X height but not for height X width for bmp image

I know title is little weird but I don't know why this is giving error.

My Task

Get the starting and ending x,y indexes from an image so I can draw a rectangle around them. Currently I'm working on to get (x,y) positions of starting and ending pixels in image.

Here is my 4 functions for 4th positions

static int[] getStartX(Bitmap bmp) //run perfect
        {
            int[] arr = new int[2];
            for (int x = 0; x < bmp.Width - 1; x++)
            {
                for (int y = 0; y < bmp.Height - 1; y++)
                {
                     Color color = bmp.GetPixel(x, y);
                     if (color.ToArgb() == Color.Black.ToArgb())
                     {
                         arr[0] = x;
                         arr[1] = y;
                         return arr;
                     }
                }
            }
            return arr;
        }
        static int[] getStartY(Bitmap bmp)
        {
            int[] arr = new int[2];
            for (int x = 0; x < bmp.Height - 1; x++)
            {
                for (int y = 0; y < bmp.Width - 1; y++)
                {
                    Color color = bmp.GetPixel(x, y); //Exception out of range
                    if (color.ToArgb() == Color.Black.ToArgb())
                    {
                        arr[0] = x;
                        arr[1] = y;
                        return arr;
                    }
                }
            }
            return arr;
        }
        static int[] getEndX(Bitmap bmp)

        {
            int[] arr = new int[2];
            for (int x = bmp.Width-1 ;  x >= 0; x--)
            {
                for (int y = bmp.Height - 1; y >=0 ; y--)
                {
                    Color color = bmp.GetPixel(x, y);//Exception out of range
                    if (color.ToArgb() == Color.Black.ToArgb())
                    {
                        arr[0] = x;
                        arr[1] = y;
                        return arr;
                    }
                }
            }
            return arr;
        }
        static int[] getENdY(Bitmap bmp)
        {
            int[] arr = new int[2];
            for (int x = bmp.Height - 1; x >= 0; x--)
            {
                for (int y = bmp.Width - 1; y >= 0; y--)
                {
                    Color color = bmp.GetPixel(x, y); //Exception out of range
                    if (color.ToArgb() == Color.Black.ToArgb())
                    {
                        arr[0] = x;
                        arr[1] = y;
                        return arr;
                    }
                }
            }
            return arr;
        }

Only my first function work correctly and all other give Exception out of range error on lines pointed in code.

Here is my Image

Expected output pixels showed in red : Output Main

static void Main(string[] args)
        {
            Bitmap bmp = new Bitmap("C:\\Users\\AV\\5.bmp");
            int[] arr = new int[2];
            arr = getStartX(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            arr = getStartY(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            arr = getEndX(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            arr = getENdY(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            bmp.Save("1.bmp");
}

Drawing blue dot on every position i want, to indicate. I want to get only 4 positions so I can draw a rectangle around it. If anyone can help me thanks in advance.

For the first exception, I think it's because you're calling GetPixel with the Height first and then the Width. You might consider using more meaningful names to help avoid confusion, but this should work:

Color color = bmp.GetPixel(y, x); 

I think giving some more meaningful names to your variables and methods might help, at least it does for me. Also, I think the methods are returning more than they need to. All you really need are the x and y coordinates of the furthest top, bottom, left and right pixels. Here are some modified methods that do that (mostly your code):

/// <summary>
/// This returns the x-coordinate of the point that is closest to the left of the image
/// </summary>
/// <param name="bmp">The image to search</param>
/// <returns>The x-coordinate of the left-most point</returns>
static int GetLeftX(Bitmap bmp)
{
    int leftmostPointX = 0;

    // Start at top left, and look down each column as we move to the right
    for (int x = 0; x < bmp.Width - 1; x++)
    {
        for (int y = 0; y < bmp.Height - 1; y++)
        {
            Color color = bmp.GetPixel(x, y);

            if (color.ToArgb() == Color.Black.ToArgb())
            {
                leftmostPointX = x;
                break;
            }
        }

        if (leftmostPointX > 0) break;
    }

    return leftmostPointX;
}

/// <summary>
/// This returns the y-coordinate of the point that is closest to the top of the image
/// </summary>
/// <param name="bmp">The image to search</param>
/// <returns>The y-coordinate of the top-most point</returns>
static int GetTopY(Bitmap bmp)
{
    int topmostPointY = 0;

    // Start at top left, and look across each row as we move down
    for (int y = 0; y < bmp.Height - 1; y++)
    {
        for (int x = 0; x < bmp.Width - 1; x++)
        {
            Color color = bmp.GetPixel(x, y);

            if (color.ToArgb() == Color.Black.ToArgb())
            {
                topmostPointY = y;
                break;
            }
        }

        if (topmostPointY > 0) break;
    }

    return topmostPointY;
}

/// <summary>
/// This returns the s-coordinate of the point that is closest to the right of the image
/// </summary>
/// <param name="bmp">The image to search</param>
/// <returns>The x-coordinate of the right-most point</returns>
static int GetRightX(Bitmap bmp)
{
    int rightmostPointX = bmp.Width - 1;

    // Start at top right, and look down each column as we move to the left
    for (int x = bmp.Width - 1; x >= 0; x--)
    {
        for (int y = 0; y < bmp.Height - 1; y++)
        {
            Color color = bmp.GetPixel(x, y);

            if (color.ToArgb() == Color.Black.ToArgb())
            {
                rightmostPointX = x;
                break;
            }
        }

        if (rightmostPointX < bmp.Width - 1) break;
    }

    return rightmostPointX;
}

/// <summary>
/// This returns the y-coordinate of the point that is closest to the right of the image
/// </summary>
/// <param name="bmp">The image to search</param>
/// <returns>The y-coordinate of the right-most point</returns>
static int GetBottomY(Bitmap bmp)
{
    int lowestPointY = bmp.Height - 1;

    // Start at bottom left, and look across each row as we move up
    for (int y = bmp.Height - 1; y >= 0; y--)
    {
        for (int x = 0; x < bmp.Width - 1; x++)
        {
            Color color = bmp.GetPixel(x, y);

            if (color.ToArgb() == Color.Black.ToArgb())
            {
                lowestPointY = y;
                break;
            }
        }

        if (lowestPointY < bmp.Height - 1) break;
    }

    return lowestPointY;
}

And then here is how I would call these methods, using meaningful names and starting with the smallest parts, then building up to what we need (from a single coordinate to an array of points):

private static void Main()
{
    // Coordinates
    int leftX = GetLeftX(bmp);
    int rightX = GetRightX(bmp);
    int topY = GetTopY(bmp);
    int bottomY = GetBottomY(bmp);

    // Create Points from the coordinates
    var topLeft = new Point(leftX, topY);
    var topRight = new Point(rightX, topY);
    var bottomLeft = new Point(leftX, bottomY);
    var bottomRight = new Point(rightX, bottomY);

    // An array of points representing our box
    var box = new[] {topLeft, topRight, bottomRight, bottomLeft, topLeft};

    // Draw a box
    var graphics = Graphics.FromImage(bmp);
    var pen = new Pen(Color.Blue);
    graphics.DrawLines(pen, box);

    // Save the new image
    bmp.Save(@"f:\public\temp\modified.bmp");
}

Thanks for helping! I've marked my mistakes!

Finally I'm getting my image! Image

MAIN

  static void Main(string[] args)
        {
            Bitmap bmp = new Bitmap("C:\\Users\\AV\\5.bmp");
            int[] arr = new int[2];
            int[] arr2 = new int[2];
            int[] arr3 = new int[2];
            int[] arr4 = new int[2];
            arr = getStartX(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            arr2 = getStartY(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            arr3 = getEndX(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            arr4 = getENdY(bmp);
            bmp.SetPixel(arr[0], arr[1], Color.Blue);
            Graphics g = Graphics.FromImage(bmp);
            g.DrawLines(new Pen(Color.Blue), new Point[]
                                                   {
                                                       new Point(arr[0], arr[1]), new Point(arr[0], arr2[1]),
                                                       new Point(arr[0], arr2[1]), new Point(arr2[0], arr2[1]),
                                                       new Point(arr2[0], arr2[1]), new Point(arr3[0], arr2[1]),
                                                       new Point(arr3[0], arr2[1]), new Point(arr3[0], arr3[1]),
                                                       new Point(arr3[0], arr3[1]), new Point(arr3[0], arr4[1]),
                                                       new Point(arr3[0], arr4[1]), new Point(arr4[0], arr4[1]),
                                                       new Point(arr4[0], arr4[1]), new Point(arr[0], arr4[1]),
                                                       new Point(arr[0], arr4[1]), new Point(arr[0], arr[1]),

                                                   });
            bmp.Save("1.bmp");
}

FUNCTIONS

 static int[] getStartX(Bitmap bmp)
        {
            int[] arr = new int[2];
            for (int x = 0; x < bmp.Width - 1; x++)
            {
                for (int y = 0; y < bmp.Height - 1; y++)
                {
                     Color color = bmp.GetPixel(x, y);
                     if (color.ToArgb() == Color.Black.ToArgb())
                     {
                         arr[0] = x-1;
                         arr[1] = y;
                         return arr;
                     }
                }
            }
            return arr;
        }
        static int[] getStartY(Bitmap bmp)
        {
            int[] arr = new int[2];
            for (int x = 0; x < bmp.Height - 1; x++)
            {
                for (int y = 0; y < bmp.Width - 1; y++)
                {
                    Color color = bmp.GetPixel(y, x); //mistake
                    if (color.ToArgb() == Color.Black.ToArgb())
                    {
                        arr[0] = y; //mistake
                        arr[1] = x-1; //mistake
                        return arr;
                    }
                }
            }
            return arr;
        }
        static int[] getEndX(Bitmap bmp)

        {
            int[] arr = new int[2];
            for (int x = bmp.Width-1 ;  x >= 0; x--)
            {
                for (int y = bmp.Height - 1; y >=0 ; y--)
                {
                    Color color = bmp.GetPixel(x, y);
                    if (color.ToArgb() == Color.Black.ToArgb())
                    {
                        arr[0] = x+1;
                        arr[1] = y;
                        return arr;
                    }
                }
            }
            return arr;
        }
        static int[] getENdY(Bitmap bmp)
        {
            int[] arr = new int[2];
            for (int x = bmp.Height - 1; x >= 0; x--)
            {
                for (int y = bmp.Width - 1; y >= 0; y--)
                {
                    Color color = bmp.GetPixel(y, x); //mistake
                    if (color.ToArgb() == Color.Black.ToArgb())
                    {
                        arr[0] = y; //mistake
                        arr[1] = x+1; //mistake
                        return arr;
                    }
                }
            }
            return arr;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM