private void SetFilter() { FormFilter = new OrderedDitheringFilter(); FormFilter.Kernel = Kernel; FormFilter.AnchorX = (Rows - 1) / 2; FormFilter.AnchorY = (Columns - 1) / 2; FormFilter.K = K; FormFilter.Dimention = Rows; }
public static Bitmap LabTask2(this Bitmap sourceBitmap, OrderedDitheringFilter filter, bool _flag) { 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 filterAnchorX = filter.AnchorX; int filterAnchorY = filter.AnchorY; int filterDimension = filter.Dimention; int indexLowerBoundX = -filterAnchorX; int indexUpperBoundX = (filterDimension - filterAnchorX) - 1; int indexLowerBoundY = -filterAnchorY; int indexUpperBoundY = (filterDimension - filterAnchorY) - 1; int K = filter.K; double[] levels = new double[K]; for (int i = 0; i < levels.Length; i++) { double interval = (float)i / (K - 1); levels[i] = interval * 255; } double[] levelsY = new double[K]; double[] levelsCr = new double[K]; double[] levelsCb = new double[K]; for (int i = 0; i < levelsY.Length; i++) { double interval = (float)i / (K - 1); levelsY[i] = 17 + interval * (235 - 17); } for (int i = 0; i < levelsCr.Length; i++) { double interval = (float)i / (K - 1); levelsCr[i] = 16 + interval * (240 - 16); } for (int i = 0; i < levelsCb.Length; i++) { double interval = (float)i / (K - 1); levelsCb[i] = 16 + interval * (240 - 16); } for (int offsetY = 0; offsetY < sourceBitmap.Height; offsetY += filter.Dimention) { for (int offsetX = 0; offsetX < sourceBitmap.Width; offsetX += filter.Dimention) { 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)) { continue; } for (int filterX = indexLowerBoundX; filterX <= indexUpperBoundX; filterX++) { int computeX = filterX * 4; if ((offsetX + filterX) < 0 || (offsetX + filterX) > (sourceBitmap.Width - 1)) { continue; } int calcOffset = byteOffset + computeY + computeX; double kernelValue = filter.Kernel[filterY + filterAnchorY][filterX + filterAnchorX]; double blue = (pixelBuffer[calcOffset]); double green = (pixelBuffer[calcOffset + 1]); double red = (pixelBuffer[calcOffset + 2]); double Y; double Cb; double Cr; if (_flag) { Y = red; Cb = green; Cr = blue; } else { Y = 16.0 + 1.0 / 256.0 * (65.738 * red + 129.057 * green + 25.064 * blue); Cb = 128.0 + 1.0 / 256.0 * (-37.945 * red - 74.494 * green + 112.439 * blue); Cr = 128.0 + 1.0 / 256.0 * (112.439 * red - 94.154 * green - 18.285 * blue); } double newY = levelsY[TakeLevelIndex(Y, kernelValue, K)]; double newCr = levelsCr[TakeLevelIndex(Cr, kernelValue, K)]; double newCb = levelsCb[TakeLevelIndex(Cb, kernelValue, K)]; double newRed = (298.082 * newY + 408.583 * newCr) / 256.0 - 222.921; if (newRed < 0) { newRed = 0; } if (newRed > 255) { newRed = 255; } double newGreen = (298.082 * newY - 100.291 * newCb - 208.120 * newCr) / 256.0 + 135.576; if (newGreen < 0) { newGreen = 0; } if (newGreen > 255) { newGreen = 255; } double newBlue = (298.082 * newY + 516.412 * newCb) / 256.0 - 276.836; if (newBlue < 0) { newBlue = 0; } if (newBlue > 255) { newBlue = 255; } if (newGreen < 0) { newGreen = 0; } resultBuffer[calcOffset] = (byte)newBlue; resultBuffer[calcOffset + 1] = (byte)newGreen; resultBuffer[calcOffset + 2] = (byte)newRed; resultBuffer[calcOffset + 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 ApplyOrderedDithering(this Bitmap sourceBitmap, OrderedDitheringFilter 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 filterAnchorX = filter.AnchorX; int filterAnchorY = filter.AnchorY; int filterDimension = filter.Dimention; int indexLowerBoundX = -filterAnchorX; int indexUpperBoundX = (filterDimension - filterAnchorX) - 1; int indexLowerBoundY = -filterAnchorY; int indexUpperBoundY = (filterDimension - filterAnchorY) - 1; int K = filter.K; double[] levels = new double[K]; for (int i = 0; i < levels.Length; i++) { double interval = (float)i / (K - 1); levels[i] = interval * 255; } for (int offsetY = 0; offsetY < sourceBitmap.Height; offsetY += filter.Dimention) { for (int offsetX = 0; offsetX < sourceBitmap.Width; offsetX += filter.Dimention) { 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)) { continue; } for (int filterX = indexLowerBoundX; filterX <= indexUpperBoundX; filterX++) { int computeX = filterX * 4; if ((offsetX + filterX) < 0 || (offsetX + filterX) > (sourceBitmap.Width - 1)) { continue; } int calcOffset = byteOffset + computeY + computeX; double kernelValue = filter.Kernel[filterY + filterAnchorY][filterX + filterAnchorX]; double blue = (pixelBuffer[calcOffset]); double green = (pixelBuffer[calcOffset + 1]); double red = (pixelBuffer[calcOffset + 2]); resultBuffer[calcOffset] = (byte)levels[TakeLevelIndex(blue, kernelValue, K)]; resultBuffer[calcOffset + 1] = (byte)levels[TakeLevelIndex(green, kernelValue, K)]; resultBuffer[calcOffset + 2] = (byte)levels[TakeLevelIndex(red, kernelValue, K)]; resultBuffer[calcOffset + 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); }