Недавно я поставил перед проблемой обрезки и изменения размера изображений.Мне нужно было обрезать «основное содержимое» изображения, например, если у меня было изображение, похожее на это: альтернативный текст http://blstb.msn.com/i/8C/10F73EB7EE231B1EA8E65EFA7D69B.jpg
результат должен быть изображением с содержанием msn без белых полей (слева исправа).
Я ищу по оси X первое и последнее изменение цвета и по оси Y то же самое.Проблема в том, что построчное прохождение изображения занимает некоторое время ... для изображения размером 2000x1600 пикселей требуется до 2 секунд, чтобы вернуть данные CropRect => x1, y1, x2, y2.
Я пыталсясделать для каждой координаты обход и остановку на первом найденном значении, но это не сработало во всех тестовых случаях. Иногда возвращаемые данные не были ожидаемыми, а продолжительность операций была одинаковой.
Есть идеи, как сократить время обхода и обнаружения прямоугольника вокруг «основного содержимого»?
public static CropRect EdgeDetection(Bitmap Image, float Threshold)
{
CropRect cropRectangle = new CropRect();
int lowestX = 0;
int lowestY = 0;
int largestX = 0;
int largestY = 0;
lowestX = Image.Width;
lowestY = Image.Height;
//find the lowest X bound;
for (int y = 0; y < Image.Height - 1; ++y)
{
for (int x = 0; x < Image.Width - 1; ++x)
{
Color currentColor = Image.GetPixel(x, y);
Color tempXcolor = Image.GetPixel(x + 1, y);
Color tempYColor = Image.GetPixel(x, y + 1);
if ((Math.Sqrt(((currentColor.R - tempXcolor.R) * (currentColor.R - tempXcolor.R)) +
((currentColor.G - tempXcolor.G) * (currentColor.G - tempXcolor.G)) +
((currentColor.B - tempXcolor.B) * (currentColor.B - tempXcolor.B))) > Threshold))
{
if (lowestX > x)
lowestX = x;
if (largestX < x)
largestX = x;
}
if ((Math.Sqrt(((currentColor.R - tempYColor.R) * (currentColor.R - tempYColor.R)) +
((currentColor.G - tempYColor.G) * (currentColor.G - tempYColor.G)) +
((currentColor.B - tempYColor.B) * (currentColor.B - tempYColor.B))) > Threshold))
{
if (lowestY > y)
lowestY = y;
if (largestY < y)
largestY = y;
}
}
}
if (lowestX < Image.Width / 4)
cropRectangle.X = lowestX - 3 > 0 ? lowestX - 3 : 0;
else
cropRectangle.X = 0;
if (lowestY < Image.Height / 4)
cropRectangle.Y = lowestY - 3 > 0 ? lowestY - 3 : 0;
else
cropRectangle.Y = 0;
cropRectangle.Width = largestX - lowestX + 8 > Image.Width ? Image.Width : largestX - lowestX + 8;
cropRectangle.Height = largestY + 8 > Image.Height ? Image.Height - lowestY : largestY - lowestY + 8;
return cropRectangle;
}
}