I\'ve image with the size of (352 x 240)
And I want to crop the white area
If you want to do it yourself you certainly can. But the details of how to do it best will depend a lot on exactly how much you know about the source image.
Here are a few questions and decisions to consider:
Looking at your example you could for example try this strategy:
For this to work you must know a little about the color changes you expect: Will there be smoothing involved? If so what level of change do you need to compare the result of the GetPixel
colors..?
Also the dimensions should either be known approximately or else you may need to repeat the whole process with a finer mesh..
Edit: Using the info from your comment one can make a few assumptions (*) and use this piece of code to determine the target rectangle. The assumptions are used to :
I use a colordistance function and 4 lists of Points and average over a few hits. The variable blur
works with values 2-6 for your image.
List<Point> xPoints1 = new List<Point>();
List<Point> xPoints2 = new List<Point>();
List<Point> yPoints1 = new List<Point>();
List<Point> yPoints2 = new List<Point>();
Rectangle findRectangle()
{
int xMax = pictureBox1.Image.Width;
int yMax = pictureBox1.Image.Height;
// * we can asume that these lines hit the body
int x0 = xMax * 3 / 4;
int y0 = yMax * 3 / 4;
using (Bitmap bmp = new Bitmap(pictureBox1.Image) )
{
// we can assume that these are the out- and inside colors
Color col0 = bmp.GetPixel(9, 9);
Color col1 = bmp.GetPixel(x0, y0);
int blur = 4;
int diff = colordistance(col0, col1) / blur;
bool outside = true;
// a few horizontal scans..
for (int y = y0 - 20; y < y0 + 20; y += 4)
{
outside = true;
for (int x = 0; x < xMax; x++)
{
Color c = bmp.GetPixel(x, y);
if ( outside && colordistance(c, col0) > diff)
{ outside = !outside; xPoints1.Add(new Point(x, y)); }
else if (!outside && colordistance(c, col1) > diff)
{ outside = !outside; xPoints2.Add(new Point(x, y)); }
}
}
// a few vertical scans..
for (int x = x0 - 20; x < x0 + 20; x += 4)
{
outside = true;
for (int y = 0; y < yMax; y++)
{
Color c = bmp.GetPixel(x, y);
if (outside && colordistance(c, col0) > diff)
{ outside = !outside; yPoints1.Add(new Point(x, y)); }
else if (!outside && colordistance(c, col1) > diff)
{ outside = !outside; yPoints2.Add(new Point(x, y)); }
}
}
int left = (int)xPoints1.Average(p => p.X);
int right = (int)xPoints2.Average(p => p.X);
int top = (int)yPoints1.Average(p => p.Y);
int bottom = (int)yPoints2.Average(p => p.Y);
// if the target sits at the bottom we didn't find the edge
if (bottom == 0) bottom = yMax;
return = new Rectangle(left, top, right - left, bottom - top);
}
}
int colordistance(Color c1, Color c2)
{
return (int) Math.Sqrt((c1.R - c2.R) * (c1.R - c2.R) +
(c1.G - c2.G) * (c1.G - c2.G) +
(c1.B - c2.B) * (c1.B - c2.B));
}
Note: The top and the left values hit the inside of the Target. The bottom (and possibly the bottom) hit the outside. So you should decrease either the former or the latter by 1 pixel, depending on your needs..!
Edit The 1st version had the outside
variable set at the wrong spot. Corrected.