Visual C ++ Ошибка рекурсивного алгоритма заливки изображения

Я пишу метод заливки, чтобы залить изображение (контур собаки) красным цветом.

В моем 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())

с такими же результатами.

Может ли кто-нибудь в уме улья представить причину и возможное решение? Огромная благодарность всем вам.

1

Решение

Есть несколько проблем. Исправьте это в первую очередь и посмотрите, что произойдет:

  1. Ты звонишь FloodFill в то время как рекурсивно r, g, а также b не все равны 0. Но вы не обновляете ни одно из этих значений в цикле while. Это дало бы вам бесконечный цикл.

  2. Другая проблема здесь:

        mid.x++;
    FloodFill(mid);
    mid.x--;
    FloodFill(mid);
    

    Пусть х будет 100. После mid.x++х будет 101. Тогда вы делаете x-- оставив вас с х = 100 снова. Итак, вы рекурсивно звоните FloodFill() с тем же значением х. Я не думаю, что это то, что вы хотели.

  3. В FloodFillВы увеличиваете x перед звонком FloodFill снова. Но вы не проверяете, достигли ли вы правой границы изображения, поэтому FloodFill будет вызываться рекурсивно с еще большими значениями x пока вы не получите переполнение стека, нарушение прав доступа или x устанавливается в 0 agein из-за целочисленного переполнения (что бы ни случилось первым).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]