Код функции Paint Bucket в C# зависает при запуске,

Я пытаюсь использовать класс стека для функции ведра с краской, но при запуске и нажатии на выбранную область в окне изображения, чтобы заполнить ее выбранным цветом, ничего не происходит, и загрузка процессора достигает 100%, и система зависает! вот код, во-первых, код окна изображения для выбора этой функции и вызова функции заполнения после нажатия:

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {

            if (act == "color")
            {

                fill(bmp ,e.X, e.Y, bmp.GetPixel(e.X, e.Y));
                pictureBox1.Image = bmp;

            }

        }

============================ и заполните функцию, которая не работает!

private void fill(Bitmap picture, int x, int y, Color bcolor)
        {

            if (x > 0 && x < picture.Width && y > 0 && y < picture.Height)
            {

                Point p = new Point(x, y);
                Stack<Point> s = new Stack<Point>();
                s.Push(p);
                while (s.Count > 0)
                {
                    p = s.Pop();
                    Color currentcolor = picture.GetPixel(p.X, p.Y);
                    if (currentcolor == bcolor)
                    {
                        //this.Refresh();
                        picture.SetPixel(p.X, p.Y, currentcolor);
                        s.Push(new Point(p.X - 1, p.Y));
                        s.Push(new Point(p.X + 1, p.Y));
                        s.Push(new Point(p.X, p.Y - 1));
                        s.Push(new Point(p.X, p.Y + 1));
                    }

                }
            }

        }

любая идея исправить эту проблему? Спасибо

--- На самом деле я удалил код "this.Refresh()", но результат тот же, ничего не изменилось! Итак, какие-либо предложения по исправлению или улучшению кода для ведра с краской?


person Bardia225    schedule 18.01.2016    source источник
comment
в чем причина использования while (s.Count › 0)   -  person IndieTech Solutions    schedule 19.01.2016
comment
Попробуйте использовать this.Refresh() вне цикла while.   -  person NPToita    schedule 19.01.2016
comment
@Alundrathedreamwalker - он Pushинг и Popпинг, поэтому я подозреваю, что s.Count > 0 в порядке.   -  person Enigmativity    schedule 19.01.2016
comment
Вы ожидаете, что пользовательский интерфейс обновится с помощью this.Refresh()?   -  person Enigmativity    schedule 19.01.2016
comment
Этот код, скорее всего, поместит в стек больше, чем вытолкнет из него, и поэтому ваш цикл может выполняться бесконечно (пока не заполнится память). Как уже упоминалось, вызов Refresh() может быть плохой идеей, когда вы рисуете ресурс, который хотите использовать в качестве изображения в пользовательском интерфейсе.   -  person Waescher    schedule 19.01.2016


Ответы (1)


Вы не можете просто назвать это:

                    s.Push(new Point(p.X - 1, p.Y));
                    s.Push(new Point(p.X + 1, p.Y));
                    s.Push(new Point(p.X, p.Y - 1));
                    s.Push(new Point(p.X, p.Y + 1));

... не проверяя, находится ли каждый p.X +/- 1 && p.Y +/- 1 в пределах Bitmap, иначе для каждого пикселя, который вы выталкиваете, вы будете нажимать 4. Это будет увеличивать стек, пока у вас не закончится память.

this.Refresh(), вероятно, заставляет код работать так медленно, что вы не видите фактического исчерпания памяти - отсюда и 100% -ный процессор. Вы должны удалить this.Refresh(), потому что ваш пользовательский интерфейс не может обновляться, пока метод fill все равно не завершится.

person Enigmativity    schedule 19.01.2016
comment
@Joey - Ты на высоте. Я должен был сказать, что Stack будет расти, пока не закончится память. - person Enigmativity; 19.01.2016
comment
Итак, какой алгоритм вы предлагаете для краски? может быть, я должен изменить весь код! - person Bardia225; 19.01.2016
comment
@ Bardia225 - Все, что вам нужно сделать, это проверить границы каждого new Point, прежде чем добавлять их в стек. И избавиться от this.Refresh(). - person Enigmativity; 20.01.2016