This example shows one approach for performing red eye reduction. Sometimes in a picture the eyes of a person or animal come out bright red. It’s an annoying effect caused by the camera’s flash bouncing off of the person’s retina. Fortunately it’s easy enough to remove red eye with a little code.
This example lets you click and drag to select an area in a picture. The program examines the pixels in the selected area and converts any that are mostly red to a grayscale. This preserves their brightness but makes them a shade of gray instead of red. The red eye effect is usually very bright so the resulting shade of gray is also bright and produces a reasonable looking result.
The program uses the RemoveRedeye method shown in the following code to convert red pixels to grayscale in a selected rectangle.
// Remove red-eye in the rectangle. private void RemoveRedeye(Bitmap bm, Rectangle rect) { for (int y = rect.Top; y <= rect.Bottom; y++) { for (int x = rect.Left; x <= rect.Right; x++) { // See if it has more red than green and blue. Color clr = bm.GetPixel(x, y); if ((clr.R > clr.G) && (clr.R > clr.B)) { // Convert to grayscale. byte new_clr = (byte)((clr.R + clr.G + clr.B) / 3); bm.SetPixel(x, y, Color.FromArgb(new_clr, new_clr, new_clr)); } } } }
This code loops over the pixels in the rectangle. If a pixel’s red component is greater than its blue and green components, the code sets all three of the pixel’s components to the average of their original values. Because the red, green, and blue components are now the same, the result is a shade of gray.
Note that this method converts any pixel that is more red than green or blue. That means if you select an area on a red coat, for example, the program will convert it to grayscale.
The face in the picture shown here has a lot of pinkish skin. Pink is basically a light shade of red so if you select parts of the face the program converts it to grayscale. To avoid that, you should be careful not to select an area bigger than necessary.




How to convert your sample in WPF?
This is a lot harder in WPF because WPF doesn’t manipulate bitmaps easily. See this post for the basics you’ll need to convert this example:
Set the pixels in a WPF bitmap in C#
Help
I’m trying yourcode on jpg and get no difference between bm and newbm
What are you trying to do? The statement Bitmap newbm = bm would make newbm just be a reference to the same bitmap so there would be no difference.
If you want to perform the red eye reduction on a copy of the bitmap, do this before you call the RemoveRedEye method:
Pingback: Recursively perform red eye reduction on a picture in C#C# Helper