private void XmlSerialization()
        {
            SetKernel();
            ConvolutionFilter convolutionFilter = CreateFilterClass(Name);
            XmlSerializer     xs = new XmlSerializer(typeof(ConvolutionFilter));
            TextWriter        tw = new StreamWriter(@".\" + Name + ".xml");

            xs.Serialize(tw, convolutionFilter);
            tw.Close();
        }
        private ConvolutionFilter CreateFilterClass(string name)
        {
            ConvolutionFilter convolutionFilter = new ConvolutionFilter();

            convolutionFilter.Name    = name;
            convolutionFilter.Factor  = 1 / Divisor;
            convolutionFilter.Bias    = Bias;
            convolutionFilter.Kernel  = Kernel;
            convolutionFilter.Offset  = Offset;
            convolutionFilter.AnchorX = AnchorX;
            convolutionFilter.AnchorY = AnchorY;

            return(convolutionFilter);
        }
        public static Bitmap ApplyConvolutionFilter(this Bitmap sourceBitmap, ConvolutionFilter filter)
        {
            BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            byte[] pixelBuffer  = new byte[sourceData.Stride * sourceData.Height];
            byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height];


            Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length);


            sourceBitmap.UnlockBits(sourceData);

            int filterHeight  = filter.Kernel.Length;
            int filterWidth   = filter.Kernel[0].Length;
            int filterAnchorX = filter.AnchorX;
            int filterAnchorY = filter.AnchorY;

            int indexLowerBoundX = -filterAnchorX;
            int indexUpperBoundX = (filterWidth - filterAnchorX) - 1;
            int indexLowerBoundY = -filterAnchorY;
            int indexUpperBoundY = (filterHeight - filterAnchorY) - 1;


            for (int offsetY = 0; offsetY < sourceBitmap.Height; offsetY++)
            {
                for (int offsetX = 0; offsetX < sourceBitmap.Width; offsetX++)
                {
                    double blue  = 0;
                    double green = 0;
                    double red   = 0;

                    int byteOffset = offsetY * sourceData.Stride + offsetX * 4;

                    for (int filterY = indexLowerBoundY; filterY <= indexUpperBoundY; filterY++)
                    {
                        int computeY = (filterY) * sourceData.Stride;

                        if ((offsetY + filterY < 0) || (offsetY + filterY) > (sourceBitmap.Height - 1))
                        {
                            computeY = (-filterY) * sourceData.Stride;
                        }

                        for (int filterX = indexLowerBoundX; filterX <= indexUpperBoundX; filterX++)
                        {
                            int computeX = filterX * 4;

                            if ((offsetX + filterX) < 0 || (offsetX + filterX) > (sourceBitmap.Width - 1))
                            {
                                computeX = (-filterX) * 4;
                            }

                            int calcOffset = byteOffset + computeY + computeX;


                            blue += (pixelBuffer[calcOffset]) * filter.Kernel[filterY + filterAnchorY] [filterX + filterAnchorX];

                            green += (pixelBuffer[calcOffset + 1]) * filter.Kernel[filterY + filterAnchorY][filterX + filterAnchorX];

                            red += (pixelBuffer[calcOffset + 2]) * filter.Kernel[filterY + filterAnchorY][filterX + filterAnchorX];
                        }
                    }


                    blue  = filter.Factor * blue + filter.Bias;
                    green = filter.Factor * green + filter.Bias;
                    red   = filter.Factor * red + filter.Bias;


                    if (blue > 255)
                    {
                        blue = 255;
                    }
                    else if (blue < 0)
                    {
                        blue = 0;
                    }

                    if (green > 255)
                    {
                        green = 255;
                    }
                    else if (green < 0)
                    {
                        green = 0;
                    }


                    if (red > 255)
                    {
                        red = 255;
                    }
                    else if (red < 0)
                    {
                        red = 0;
                    }


                    resultBuffer[byteOffset]     = (byte)(blue);
                    resultBuffer[byteOffset + 1] = (byte)(green);
                    resultBuffer[byteOffset + 2] = (byte)(red);
                    resultBuffer[byteOffset + 3] = 255;
                }
            }

            Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);


            BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);


            Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length);
            resultBitmap.UnlockBits(resultData);


            return(resultBitmap);
        }