Я пишу метод заливки, чтобы залить изображение (контур собаки) красным цветом.
В моем TestShellDlg.cpp это метод заливки. Член CTestShellDlg :: m_pScreenDib является классом растровых изображений CDIB32, который содержит графику и рисует ее.
Я хочу сэмплировать текущий пиксель и, если он не черный (цвет контура), то его цвет красный. Это предварительно собранный метод получения в классе Dib32.cpp:
void CDIB32::GetRGB(int x, int y, BYTE& r, BYTE& g, BYTE& b)
{
if (x >= Width() || y >= Height())
IERROR;
int off = y * ByteWid() + x * 4;
b = m_pBits[off];
g = m_pBits[off+1];
r = m_pBits[off+2];
}
А вот мой метод залива в классе TestShellDlg.cpp:
void CTestShellDlg::FloodFill(CPoint& mid)
{
byte r,g,b;
//while the current pixel colour is not black, set it to red and recursively loop
m_pScreenDib ->GetRGB(mid.x,mid.y, (byte) r,(byte) g,(byte)b);
while(r !=(byte)0, g !=(byte)0, b !=(byte)0)
{
m_pScreenDib -> SetRGB(mid.x, mid.y,(byte)255,(byte) 0,(byte) 0);
mid.x++;
FloodFill(mid);
mid.x--;
FloodFill(mid);
mid.y++;
FloodFill(mid);
mid.y--;
FloodFill(mid);
}
}
При создании и запуске проекта я получаю точку останова в IERROR в функции GetRGB ().
Работая через стек, это происходит в середине.x— после нескольких прогонов. Кажется, что программа никогда не доходит до mid.y ++.
Я также попробовал это как мое условие остановки:
while(mid.x < m_pScreenDib ->Width() && mid.y < m_pScreenDib -> Height())
с такими же результатами.
Может ли кто-нибудь в уме улья представить причину и возможное решение? Огромная благодарность всем вам.
Есть несколько проблем. Исправьте это в первую очередь и посмотрите, что произойдет:
Ты звонишь FloodFill
в то время как рекурсивно r
, g
, а также b
не все равны 0. Но вы не обновляете ни одно из этих значений в цикле while. Это дало бы вам бесконечный цикл.
Другая проблема здесь:
mid.x++;
FloodFill(mid);
mid.x--;
FloodFill(mid);
Пусть х будет 100. После mid.x++
х будет 101. Тогда вы делаете x--
оставив вас с х = 100 снова. Итак, вы рекурсивно звоните FloodFill()
с тем же значением х. Я не думаю, что это то, что вы хотели.
В FloodFill
Вы увеличиваете x
перед звонком FloodFill
снова. Но вы не проверяете, достигли ли вы правой границы изображения, поэтому FloodFill
будет вызываться рекурсивно с еще большими значениями x
пока вы не получите переполнение стека, нарушение прав доступа или x
устанавливается в 0 agein из-за целочисленного переполнения (что бы ни случилось первым).
Других решений пока нет …