Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Я записал код, чтобы сделать это сам - не слишком трудно получить движение основ.
По существу, необходимо просканировать пиксельные строки/столбцы, чтобы проверить на цветные пиксели и изолировать границы образа товара, затем создать новый битовый массив только с тем регионом.
Примечание это, в то время как Bitmap.GetPixel()
работы метода, это относительно медленно. Если время обработки будет важно, необходимо будет использовать Bitmap.LockBits()
для блокировки битового массива в памяти, и затем некоторого простого использования указателя в unsafe { }
блок для доступа к пикселям непосредственно.
Эта статья о CodeProject предоставляет еще некоторую подробную информацию, которую Вы, вероятно, найдете полезным.
Это, конечно, возможно. В псевдокоде:
topmost = 0
for row from 0 to numRows:
if allWhiteRow(row):
topmost = row
else:
# found first non-white row from top
break
botmost = 0
for row from numRows-1 to 0:
if allWhiteRow(row):
botmost = row
else:
# found first non-white row from bottom
break
И так же для левого и правого.
код для allWhiteRow
вовлек бы рассмотрение пикселей в ту строку и проверку, что они - весь близкий к 255,255,255.
pnmcrop
утилита от netpbm
графическая библиотека утилит делает точно это.
я предлагаю смотреть на их код, доступный от http://netpbm.sourceforge.net/
Вот мое (довольно длинное) решение:
public Bitmap Crop(Bitmap bmp)
{
int w = bmp.Width, h = bmp.Height;
Func<int, bool> allWhiteRow = row =>
{
for (int i = 0; i < w; ++i)
if (bmp.GetPixel(i, row).R != 255)
return false;
return true;
};
Func<int, bool> allWhiteColumn = col =>
{
for (int i = 0; i < h; ++i)
if (bmp.GetPixel(col, i).R != 255)
return false;
return true;
};
int topmost = 0;
for (int row = 0; row < h; ++row)
{
if (allWhiteRow(row))
topmost = row;
else break;
}
int bottommost = 0;
for (int row = h - 1; row >= 0; --row)
{
if (allWhiteRow(row))
bottommost = row;
else break;
}
int leftmost = 0, rightmost = 0;
for (int col = 0; col < w; ++col)
{
if (allWhiteColumn(col))
leftmost = col;
else
break;
}
for (int col = w-1; col >= 0; --col)
{
if (allWhiteColumn(col))
rightmost = col;
else
break;
}
int croppedWidth = rightmost - leftmost;
int croppedHeight = bottommost - topmost;
try
{
Bitmap target = new Bitmap(croppedWidth, croppedHeight);
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(bmp,
new RectangleF(0, 0, croppedWidth, croppedHeight),
new RectangleF(leftmost, topmost, croppedWidth, croppedHeight),
GraphicsUnit.Pixel);
}
return target;
}
catch (Exception ex)
{
throw new Exception(
string.Format("Values are topmost={0} btm={1} left={2} right={3}", topmost, bottommost, leftmost, rightmost),
ex);
}
}