/// <summary>
        /// Average Colors Filter
        /// </summary>
        /// <param name="sourceBitmap">Set source Bitmap</param>
        /// <param name="matrixSize">Set Matrix Size</param>
        /// <param name="applyBlue">Apply Blue</param>
        /// <param name="applyGreen">Apply Green</param>
        /// <param name="applyRed">Apply Red</param>
        /// <param name="shiftType">Set Shift Type</param>
        /// <returns></returns>
        public static System.Drawing.Bitmap AverageColoursFilter(this System.Drawing.Bitmap sourceBitmap,
                                                                 int matrixSize,
                                                                 bool applyBlue           = true,
                                                                 bool applyGreen          = true,
                                                                 bool applyRed            = true,
                                                                 ColorShiftType shiftType =
                                                                 ColorShiftType.None)
        {
            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 filterOffset = (matrixSize - 1) / 2;
            int calcOffset   = 0;

            int byteOffset = 0;

            int blue  = 0;
            int green = 0;
            int red   = 0;

            List <int> sortList = new List <int>();

            for (int offsetY = filterOffset; offsetY <
                 sourceBitmap.Height - filterOffset; offsetY++)
            {
                for (int offsetX = filterOffset; offsetX <
                     sourceBitmap.Width - filterOffset; offsetX++)
                {
                    byteOffset = offsetY *
                                 sourceData.Stride +
                                 offsetX * 4;

                    blue  = 0;
                    green = 0;
                    red   = 0;

                    for (int filterY = -filterOffset;
                         filterY <= filterOffset; filterY++)
                    {
                        for (int filterX = -filterOffset;
                             filterX <= filterOffset; filterX++)
                        {
                            calcOffset = byteOffset +
                                         (filterX * 4) +
                                         (filterY * sourceData.Stride);

                            blue  += pixelBuffer[calcOffset];
                            green += pixelBuffer[calcOffset + 1];
                            red   += pixelBuffer[calcOffset + 2];
                        }
                    }

                    blue  = blue / matrixSize;
                    green = green / matrixSize;
                    red   = red / matrixSize;

                    if (applyBlue == false)
                    {
                        blue = pixelBuffer[byteOffset];
                    }

                    if (applyGreen == false)
                    {
                        green = pixelBuffer[byteOffset + 1];
                    }

                    if (applyRed == false)
                    {
                        red = pixelBuffer[byteOffset + 2];
                    }

                    if (shiftType == ColorShiftType.None)
                    {
                        resultBuffer[byteOffset]     = (byte)blue;
                        resultBuffer[byteOffset + 1] = (byte)green;
                        resultBuffer[byteOffset + 2] = (byte)red;
                        resultBuffer[byteOffset + 3] = 255;
                    }
                    else if (shiftType == ColorShiftType.ShiftLeft)
                    {
                        resultBuffer[byteOffset]     = (byte)green;
                        resultBuffer[byteOffset + 1] = (byte)red;
                        resultBuffer[byteOffset + 2] = (byte)blue;
                        resultBuffer[byteOffset + 3] = 255;
                    }
                    else if (shiftType == ColorShiftType.ShiftRight)
                    {
                        resultBuffer[byteOffset]     = (byte)red;
                        resultBuffer[byteOffset + 1] = (byte)blue;
                        resultBuffer[byteOffset + 2] = (byte)green;
                        resultBuffer[byteOffset + 3] = 255;
                    }
                }
            }

            System.Drawing.Bitmap resultBitmap = new System.Drawing.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);
        }
예제 #2
0
        public static Bitmap AverageColoursFilter(this Bitmap sourceBitmap, 
                                                int matrixSize,  
                                                bool applyBlue = true,
                                                bool applyGreen = true,
                                                bool applyRed = true,
                                                ColorShiftType shiftType =
                                                ColorShiftType.None)
        {
            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 filterOffset = (matrixSize - 1) / 2;
            int calcOffset = 0;

            int byteOffset = 0;

            int blue = 0;
            int green = 0;
            int red = 0;

            List<int> sortList = new List<int>();

            for (int offsetY = filterOffset; offsetY <
                sourceBitmap.Height - filterOffset; offsetY++)
            {
                for (int offsetX = filterOffset; offsetX <
                    sourceBitmap.Width - filterOffset; offsetX++)
                {
                    byteOffset = offsetY *
                                 sourceData.Stride +
                                 offsetX * 4;

                    blue = 0;
                    green = 0;
                    red = 0;

                    for (int filterY = -filterOffset;
                        filterY <= filterOffset; filterY++)
                    {
                        for (int filterX = -filterOffset;
                            filterX <= filterOffset; filterX++)
                        {

                            calcOffset = byteOffset +
                                         (filterX * 4) +
                                         (filterY * sourceData.Stride);

                            blue += pixelBuffer[calcOffset];
                            green += pixelBuffer[calcOffset + 1];
                            red += pixelBuffer[calcOffset + 2];
                        }
                    }

                    blue = blue / matrixSize;
                    green = green / matrixSize;
                    red = red / matrixSize;

                    if (applyBlue == false)
                    {
                        blue = pixelBuffer[byteOffset];
                    }

                    if (applyGreen == false)
                    {
                        green = pixelBuffer[byteOffset + 1];
                    }

                    if (applyRed == false)
                    {
                        red = pixelBuffer[byteOffset + 2];
                    }

                    if (shiftType == ColorShiftType.None)
                    {
                        resultBuffer[byteOffset] = (byte)blue;
                        resultBuffer[byteOffset + 1] = (byte)green;
                        resultBuffer[byteOffset + 2] = (byte)red;
                        resultBuffer[byteOffset + 3] = 255;
                    }
                    else if (shiftType == ColorShiftType.ShiftLeft)
                    {
                        resultBuffer[byteOffset] = (byte)green;
                        resultBuffer[byteOffset + 1] = (byte)red;
                        resultBuffer[byteOffset + 2] = (byte)blue;
                        resultBuffer[byteOffset + 3] = 255;
                    }
                    else if (shiftType == ColorShiftType.ShiftRight)
                    {
                        resultBuffer[byteOffset] = (byte)red;
                        resultBuffer[byteOffset + 1] = (byte)blue;
                        resultBuffer[byteOffset + 2] = (byte)green;
                        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;
        }
        public static Bitmap AbstractColorsFilter(this Bitmap sourceBitmap,
                                                  int matrixSize,
                                                  byte edgeThreshold,
                                                  bool applyBlue           = true,
                                                  bool applyGreen          = true,
                                                  bool applyRed            = true,
                                                  EdgeTracingType edgeType =
                                                  EdgeTracingType.Black,
                                                  ColorShiftType shiftType =
                                                  ColorShiftType.None)
        {
            Bitmap edgeBitmap =
                sourceBitmap.GradientBasedEdgeDetectionFilter(edgeThreshold);

            Bitmap colorBitmap =
                sourceBitmap.AverageColoursFilter(matrixSize,
                                                  applyBlue, applyGreen, applyRed, shiftType);

            byte[] edgeBuffer   = edgeBitmap.GetByteArray();
            byte[] colorBuffer  = colorBitmap.GetByteArray();
            byte[] resultBuffer = colorBitmap.GetByteArray();

            for (int k = 0; k + 4 < edgeBuffer.Length; k += 4)
            {
                if (edgeBuffer[k] == 255)
                {
                    switch (edgeType)
                    {
                    case EdgeTracingType.Black:
                        resultBuffer[k]     = 0;
                        resultBuffer[k + 1] = 0;
                        resultBuffer[k + 2] = 0;
                        break;

                    case EdgeTracingType.White:
                        resultBuffer[k]     = 255;
                        resultBuffer[k + 1] = 255;
                        resultBuffer[k + 2] = 255;
                        break;

                    case EdgeTracingType.HalfIntensity:
                        resultBuffer[k]     = ClipByte(resultBuffer[k] * 0.5);
                        resultBuffer[k + 1] = ClipByte(resultBuffer[k + 1] * 0.5);
                        resultBuffer[k + 2] = ClipByte(resultBuffer[k + 2] * 0.5);
                        break;

                    case EdgeTracingType.DoubleIntensity:
                        resultBuffer[k]     = ClipByte(resultBuffer[k] * 2);
                        resultBuffer[k + 1] = ClipByte(resultBuffer[k + 1] * 2);
                        resultBuffer[k + 2] = ClipByte(resultBuffer[k + 2] * 2);
                        break;

                    case EdgeTracingType.ColorInversion:
                        resultBuffer[k]     = ClipByte(255 - resultBuffer[k]);
                        resultBuffer[k + 1] = ClipByte(255 - resultBuffer[k + 1]);
                        resultBuffer[k + 2] = ClipByte(255 - resultBuffer[k + 2]);
                        break;
                    }
                }
            }

            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);
        }