Рекурсивно выполнять уменьшение эффекта «красных глаз» на изображении в C#
Пример
В этой программе используется другой подход к выбору пикселей для преобразования. Когда вы нажимаете на пиксель, выполняется следующий код.
// Выполнение эффекта «красных глаз», начиная с щелчка. private void picImage_MouseClick(object sender, MouseEventArgs e) { Bitmap bm = (Bitmap)picImage.Image; RemoveRedEyeAtPoint(1, bm, e.X, e.Y); picImage.Image = bm; }
Этот код в основном просто вызывает следующий рекурсивный метод RemoveRedEyeAtPoint, передавая ему точку, которую вы нажали.
// Удаление красных глаз в прямоугольнике. private void RemoveRedEyeAtPoint(int depth, Bitmap bm, int x, int y) { // Не повторяйте слишком глубоко. if (depth > 100) return; // Не делайте ничего, если этот пиксель не в основном красный. Color clr = bm.GetPixel(x, y); if ((clr.R <= clr.G + 10) || (clr.R <= clr.B + 10)) return; // Удалите красные глаза в этот момент. byte new_clr = (byte)((clr.R + clr.G + clr.B) / 3); bm.SetPixel(x, y, Color.FromArgb(new_clr, new_clr, new_clr)); // Проверяем соседние пиксели. int min_x = Math.Max(x - 1, 0); int max_x = Math.Min(x + 1, bm.Width - 1); int min_y = Math.Max(y - 1, 0); int max_y = Math.Min(y + 1, bm.Height - 1); for (int new_x = min_x; new_x <= max_x; new_x++) { for (int new_y = min_y; new_y <= max_y; new_y++) { if ((new_x != 0) || (new_y != 0)) RemoveRedEyeAtPoint(depth + 1, bm, new_x, new_y); } } }
Этот метод вызывает себя рекурсивно, поэтому он сначала проверяет, что его глубина рекурсии не слишком глубока. Если он этого не сделал, и вы нажали на большую красную область на изображении, метод будет называть себя рекурсивно, пока не заполнит стек программы и не разбился. Этот тест просто устанавливает верхнюю границу того, сколько раз метод будет рекурсивно. (Если вам действительно нужно преобразовать огромную красную область в оттенки серого, просто щелкните по ней несколько раз.)
Далее код получает цвет своего целевого пикселя. Если этот цвет не является главным образом красным, метод возвращается. В этой версии я добавил небольшое смещение, поэтому красный компонент должен быть как минимум на 10 больше, чем зеленые компоненты синего цвета. Это не позволяет методу преобразовать пиксели, которые в основном серые, но имеют бесконечно красное, чем зеленое или синее.
Если код делает это так далеко, он преобразует целевой пиксель в оттенки серого.
Затем программа перебирает соседние пиксели и рекурсивно вызывает себя, чтобы проверить их на красные пиксели.