/// <summary>
        /// XML Deserialize
        /// </summary>
        /// <param name="xmlString">Set XML string</param>
        /// <returns></returns>
        public static ImageBlendingBitmapFilterData XmlDeserialize(string xmlString)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ImageBlendingBitmapFilterData));
            MemoryStream  memoryStream  = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));

            XmlReader xmlReader = XmlReader.Create(memoryStream);

            ImageBlendingBitmapFilterData filterData = null;

            if (xmlSerializer.CanDeserialize(xmlReader) == true)
            {
                xmlReader.Close();
                memoryStream.Position = 0;

                filterData = (ImageBlendingBitmapFilterData)xmlSerializer.Deserialize(memoryStream);
            }

            memoryStream.Close();
            memoryStream.Dispose();

            return(filterData);
        }
        /// <summary>
        /// XML Serialization
        /// </summary>
        /// <param name="filterData">Set Bitmap Filter</param>
        /// <returns></returns>
        public static string XmlSerialize(ImageBlendingBitmapFilterData filterData)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ImageBlendingBitmapFilterData));

            XmlWriterSettings xmlSettings = new XmlWriterSettings();

            xmlSettings.Encoding = Encoding.UTF8;
            xmlSettings.Indent   = true;

            MemoryStream memoryStream = new MemoryStream();
            XmlWriter    xmlWriter    = XmlWriter.Create(memoryStream, xmlSettings);

            xmlSerializer.Serialize(xmlWriter, filterData);
            xmlWriter.Flush();

            string xmlString = xmlSettings.Encoding.GetString(memoryStream.ToArray());

            xmlWriter.Close();
            memoryStream.Close();
            memoryStream.Dispose();

            return(xmlString);
        }
        /// <summary>
        /// Blend Image
        /// </summary>
        /// <param name="baseImage">Set source Bitmap</param>
        /// <param name="overlayImage">Set overlay Bitmap</param>
        /// <param name="filterData">Set filter</param>
        /// <returns></returns>
        public static System.Drawing.Bitmap BlendImage(this System.Drawing.Bitmap baseImage, System.Drawing.Bitmap overlayImage, ImageBlendingBitmapFilterData filterData)
        {
            BitmapData baseImageData = baseImage.LockBits(new Rectangle(0, 0, baseImage.Width, baseImage.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            byte[] baseImageBuffer = new byte[baseImageData.Stride * baseImageData.Height];

            Marshal.Copy(baseImageData.Scan0, baseImageBuffer, 0, baseImageBuffer.Length);

            BitmapData overlayImageData = overlayImage.LockBits(new Rectangle(0, 0, overlayImage.Width, overlayImage.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            byte[] overlayImageBuffer = new byte[overlayImageData.Stride * overlayImageData.Height];

            Marshal.Copy(overlayImageData.Scan0, overlayImageBuffer, 0, overlayImageBuffer.Length);

            float sourceBlue  = 0;
            float sourceGreen = 0;
            float sourceRed   = 0;

            float overlayBlue  = 0;
            float overlayGreen = 0;
            float overlayRed   = 0;

            for (int k = 0; k < baseImageBuffer.Length && k < overlayImageBuffer.Length; k += 4)
            {
                sourceBlue  = (filterData.SourceBlueEnabled ? baseImageBuffer[k] * filterData.SourceBlueLevel : 0);
                sourceGreen = (filterData.SourceGreenEnabled ? baseImageBuffer[k + 1] * filterData.SourceGreenLevel : 0);
                sourceRed   = (filterData.SourceRedEnabled ? baseImageBuffer[k + 2] * filterData.SourceRedLevel : 0);

                overlayBlue  = (filterData.OverlayBlueEnabled ? overlayImageBuffer[k] * filterData.OverlayBlueLevel : 0);
                overlayGreen = (filterData.OverlayGreenEnabled ? overlayImageBuffer[k + 1] * filterData.OverlayGreenLevel : 0);
                overlayRed   = (filterData.OverlayRedEnabled ? overlayImageBuffer[k + 2] * filterData.OverlayRedLevel : 0);

                baseImageBuffer[k]     = CalculateColorComponentBlendValue(sourceBlue, overlayBlue, filterData.BlendTypeBlue);
                baseImageBuffer[k + 1] = CalculateColorComponentBlendValue(sourceGreen, overlayGreen, filterData.BlendTypeGreen);
                baseImageBuffer[k + 2] = CalculateColorComponentBlendValue(sourceRed, overlayRed, filterData.BlendTypeRed);
            }

            System.Drawing.Bitmap bitmapResult    = new System.Drawing.Bitmap(baseImage.Width, baseImage.Height, PixelFormat.Format32bppArgb);
            BitmapData            resultImageData = bitmapResult.LockBits(new Rectangle(0, 0, bitmapResult.Width, bitmapResult.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            Marshal.Copy(baseImageBuffer, 0, resultImageData.Scan0, baseImageBuffer.Length);

            bitmapResult.UnlockBits(resultImageData);
            baseImage.UnlockBits(baseImageData);
            overlayImage.UnlockBits(overlayImageData);

            return(bitmapResult);
        }