Image Processor


Objective:

An easy interactive application that's able to load images (one per time) and apply different filtering algorithms on it (just modifying the bitmap, not adding new layers). Interface: Not much to be said here. Open File - this component is presented in another article on c-sharp corner so I won't go in details here. The only thing I want to add is, regarding the file filter, I had problems finding out how to add more then one file extension to a filter index.

openFileDialog1.Filter = "Bitmap Files (*.bmp)|*.bmp|" +

"JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|" +

"GIF (*.GIF)|*.GIF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO|" +

"All Picture Files|*.bmp;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.TIF;*.TIFF;*.PNG;*.ICO|All Files (*.*)|*.*";


There's also (commented) an alternative version for the brightness filter. It offers a preview of the filter you are going to use and gives you the ability to select the intensity of the filter by using a track bar (slider). It has a bug and the OK button isn't functional. But it is quite easy to repair the bug (I didn't have the time and I already started working on a new project). The preview image doesn't use the original image to brighten but rather the already brightened image that was formerly preview.

Filters:

I won't go in details since my goal was to apply the filters, not improve/modify them.

Invert:

Bitmap b = new Bitmap("temp");

BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),

ImageLockMode.ReadWrite, b.PixelFormat);

int stride = bmData.Stride;

System.IntPtr Scan0 = bmData.Scan0;

unsafe

{

    byte* p = (byte*)(void*)Scan0;

    int nOffset = stride - b.Width*3;

    int nWidth = b.Width * 3;

    for (int y = 0; y < b.Height; ++y)

    {

        for (int x = 0; x < nWidth; ++x)

        {

            p[0] = (byte)(255 - p[0]);

            ++p;

        }

        p += nOffset;

    }

}

b.UnlockBits(bmData);

b.Save("temp~");

b.Dispose();

System.IO.File.Copy("temp~", "temp", true);

System.IO.File.Delete("temp~");


Grayscale:

unsafe

{

    byte* p = (byte*)(void*)Scan0;

    int nOffset = stride - b.Width * 3;

    byte red, green, blue;

    for (int y = 0; y < b.Height; ++y)

    {

        for (int x = 0; x < b.Width; ++x)

        {

            blue = p[0];

            green = p[1];

            red = p[2];

 

            p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);

            p += 3;

        }

        p += nOffset;

    }

}


Brightness:

unsafe

{

    byte* p = (byte*)(void*)Scan0; 

    int nOffset = stride - b.Width * 3; 

    int nBrightness = (int)value.Value, nVal; 

    for (int y = 0; y < b.Height; ++y)

    {

        for (int x = 0; x < b.Width * 3; ++x)

        {

            nVal = (int)(p[0] + nBrightness);

 

            if (nVal < 0) nVal = 0;

                if (nVal > 255) nVal = 255;

 

                p[0] = (byte)nVal;

 

                ++p;

        }

        p += nOffset;

    }

}


Contrast:

unsafe

{

    byte* p = (byte*)(void*)Scan0; 

    int nOffset = stride - b.Width * 3; 

    double contrast = (100.0 + (int)value.Value) / 100, pixel = 0; 

    byte red, green, blue; 

    for (int y = 0; y < b.Height; ++y)

    {

        for (int x = 0; x < b.Width; ++x)

        {

            blue = p[0];

            green = p[1];

            red = p[2];

 

            pixel = blue / 255.0;

            pixel -= 0.5;

            pixel *= contrast;

            pixel += 0.5;

            pixel *= 255;

            if (pixel < 0) pixel = 0;

            if (pixel > 255) pixel = 255;

            p[0] = (byte)pixel;

 

            pixel = green / 255.0;

            pixel -= 0.5;

            pixel *= contrast;

            pixel += 0.5;

            pixel *= 255;

            if (pixel < 0) pixel = 0;

            if (pixel > 255) pixel = 255;

            p[1] = (byte)pixel;

 

            pixel = red / 255.0;

            pixel -= 0.5;

            pixel *= contrast;

            pixel += 0.5;

            pixel *= 255;

            if (pixel < 0) pixel = 0;

            if (pixel > 255) pixel = 255;

            p[2] = (byte)pixel;

 

            p += 3;

        }

        p += nOffset;

    }

}


These are the per pixel filters. Next are the Convolution Filters. I used a 3x3 matrix.

BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

 

int stride = bmData.Stride;

int stride2 = stride * 2;

System.IntPtr Scan0 = bmData.Scan0;

System.IntPtr SrcScan0 = bmSrc.Scan0;

 

unsafe

{

    byte * p = (byte *)(void *)Scan0;

    byte * pSrc = (byte *)(void *)SrcScan0;

 

    int nOffset = stride + 6 - b.Width*3;

    int nWidth = b.Width - 2;

    int nHeight = b.Height - 2; 

    int nPixel;

 

    for(int y=0;y < nHeight;++y)

    {

        for(int x=0; x < nWidth; ++x )

        {

            nPixel = ( ( ( (pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) +

            (pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) +

            (pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] *

            m.BottomRight)) / m.Factor) + m.Offset);

 

            if (nPixel < 0) nPixel = 0;

            if (nPixel > 255) nPixel = 255;

 

            p[5 + stride]= (byte)nPixel;

 

            nPixel = ( ( ( (pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) +

            (pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) +

            (pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] *

            m.BottomRight)) / m.Factor) + m.Offset);

 

            if (nPixel < 0) nPixel = 0;

            if (nPixel > 255) nPixel = 255;

                                                                  

            p[4 + stride] = (byte)nPixel;

 

            nPixel = ( ( ( (pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) +

            (pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) +

            (pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] *

            m.BottomRight)) / m.Factor) + m.Offset);

 

            if (nPixel < 0) nPixel = 0;

            if (nPixel > 255) nPixel = 255;

 

            p[3 + stride] = (byte)nPixel;

 

            p += 3;

            pSrc += 3;

        }

 

        p += nOffset;

        pSrc += nOffset;

    }

} 

b.UnlockBits(bmData);

bSrc.UnlockBits(bmSrc); 

b.Save("temp~");

b.Dispose();

bSrc.Dispose();

Applying the filters was only a problem of modifying the Convolution Matrix.  


Recommended Free Ebook
Similar Articles