2013-06-27 90 views
0

我正在寫一個洪水填充方法來填充紅色的圖像(狗的輪廓)。C++洪水填充圖像遞歸算法錯誤

在我的TestShellDlg.cpp是洪水填充方法。 CTestShellDlg :: m_pScreenDib成員是包含圖形並繪製它們的CDIB32位圖類。

我想對當前像素進行採樣,如果它不是黑色(輪廓的顏色),則將其着色爲紅色。這是Dib32.cpp類預建的getter:

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類我floodfill方法:

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); 
     } 

} 

在構建和運行項目,我得到一個在GetRGB()函數中的IERROR中斷點。

通過堆棧工作,發生在mid.x--幾次運行之後。該程序似乎從來沒有使mid.y ++。

我也試過這個作爲我的停止條件:

while(mid.x < m_pScreenDib ->Width() && mid.y < m_pScreenDib -> Height()) 

具有相同的結果。

蜂房中的任何人都可以提供原因和可能的解決方案嗎?非常感謝大家。

+1

堆棧溢出?請記住,函數調用會在堆棧上分配內存,並且堆棧是有限的。你*有使用遞歸嗎? –

+0

好的,謝謝你,我不必使用遞歸。這只是我確保覆蓋每個像素的方法。我想我必須採取不同的方式。謝謝。 –

回答

1

有幾個問題。解決這些第一,看看會發生什麼:

  1. 要調用FloodFill遞歸而rgb並不都等於0。但是,你不更新任何在你的while循環這些值。那會給你一個無限循環。

  2. 的另一個問題是在這裏:

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

    設x 100 mid.x++後,x是101.然後,你做x--讓你有X = 100一次。所以你遞歸調用FloodFill()具有相同的x值。我不認爲這就是你的意圖。

  3. FloodFill中,您在增加x之前再次調用FloodFill。但是你不檢查你是否已經到達圖像的右邊界,所以FloodFill將被遞歸地調用,並且具有更大的值x,直到你得到一個stackoverflow,一個訪問衝突或x被設置爲0 agein,因爲整數溢出(無論先發生什麼)。

+0

嗯,謝謝你!在第1點,雖然,我沒有改變這一行的像素值: 'code m_pScreenDib - > SetRGB(mid.x,mid。y,(byte)255,(byte)0,(byte)0);' –

+0

@RyanRDizzleGraham是的,你改變像素值,但不是*變量*'r','g'和'b'。 –

+0

因此也同時將它們設置爲r = 255,g = 0,b = 0? –