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