I started Cool Camera as a stop gap application trying to figure my way around SatNav app (which started while i was answering some posts on AppHub forums). Current availble version stands at 1.6 and 1.7 is with Microsoft.
It has come a long way since 1.0 – which only supported: Taking pictures and a camera style HUD. The picture viewer was very basic. Just display the image in Image control. Since then i have * added support for filters, added video recording and playback, added album viewer. I have worked a bit more on image processing and i am a bit better at image processing.
The first set of filters were added to app thanks to René Schulte – http://kodierer.blogspot.co.uk/. I remember coming across http://picfx.codeplex.com a while back and it provided very handy way to creating and applying effects to WriteableBitmaps. I used the few supplied to get stared however before long i was asked if i could provide a way of making images darker. The most common scenario is when you use flash and the images are too white – especially faces. As i started, i remembered face detection post by Rene. http://channel9.msdn.com/coding4fun/articles/FaceLight–Silverlight-4-Real-Time-Face-Detection.
I started with Rene’s YCbCr code and the first pass to detect whether color falls into skin tone range. The first pass for skin tone detection worked just fine, how search began on how to increase or decrease luminance of image. I came across HSLColor which had an ligthen / darken method but that did’t work so eventually, i used Lerp
public int[] Process(int[] inputPixels, int width, int height)
{
var resultPixels = new int[inputPixels.Length];
// Threshold every pixel
for (int i = 0; i < inputPixels.Length; i++)
{
int c = inputPixels[i];
var ycbcr = YCbCrColor.FromArgbColori(c);
if (ycbcr.Y >= LowerThreshold.Y && ycbcr.Y <= UpperThreshold.Y
&& ycbcr.Cb >= LowerThreshold.Cb && ycbcr.Cb <= UpperThreshold.Cb
&& ycbcr.Cr >= LowerThreshold.Cr && ycbcr.Cr <= UpperThreshold.Cr)
{
// skin tone match
System.Windows.Media.Color sc = System.Windows.Media.Color.FromArgb((byte)(c >> 24), (byte)(c >> 16), (byte)(c >> 8), (byte)c);
Microsoft.Xna.Framework.Color xc = new Microsoft.Xna.Framework.Color(sc.R, sc.G, sc.B, sc.A);
xc = Color.Lerp(xc, Color, Amout);
c = (255 << 24) | ((byte)(xc.R > 255 ? 255 : xc.R) << 16) | ((byte)(xc.G > 255 ? 255 : xc.G) << 8) | (byte)(xc.B > 255 ? 255 : xc.B);
}
resultPixels[i] = c;
}
return resultPixels;
}
Now all you need to do is pass the amount to Lerp and the color. To Darken you pass Black, to lighten, you pass White.