/// <summary> /// Floyd-Steinberg error diffusion algorithm /// </summary> private void ErrorDiffusion() { dithering_texture = DirectBitmap.FromBitmap(original_texture.Bitmap); int width = original_texture.Width; int height = original_texture.Height; int R, G, B; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Color px = dithering_texture.GetPixel(x, y); R = FindClosestColor(px.R, Kr); G = FindClosestColor(px.G, Kg); B = FindClosestColor(px.B, Kb); dithering_texture.SetPixel(x, y, Color.FromArgb(R, G, B)); float errr, errg, errb; errr = (float)px.R - R; errg = (float)px.G - G; errb = (float)px.B - B; if (x + 1 < width) { Color cx = dithering_texture.GetPixel(x + 1, y); int r = cx.R + (int)errr * 7 / 16; r = CorrectValue(r); int g = cx.G + (int)errg * 7 / 16; g = CorrectValue(g); int b = cx.B + (int)errb * 7 / 16; b = CorrectValue(b); dithering_texture.SetPixel(x + 1, y, Color.FromArgb(r, g, b)); } if (x - 1 >= 0 && y + 1 < height) { Color cx = dithering_texture.GetPixel(x - 1, y + 1); int r = cx.R + (int)errr * 3 / 16; r = CorrectValue(r); int g = cx.G + (int)errg * 3 / 16; g = CorrectValue(g); int b = cx.B + (int)errb * 3 / 16; b = CorrectValue(b); dithering_texture.SetPixel(x - 1, y + 1, Color.FromArgb(r, g, b)); } if (y + 1 < height) { Color cx = dithering_texture.GetPixel(x, y + 1); int r = cx.R + (int)errr * 5 / 16; r = CorrectValue(r); int g = cx.G + (int)errg * 5 / 16; g = CorrectValue(g); int b = cx.B + (int)errb * 5 / 16; b = CorrectValue(b); dithering_texture.SetPixel(x, y + 1, Color.FromArgb(r, g, b)); } if (x + 1 < width && y + 1 < height) { Color cx = dithering_texture.GetPixel(x + 1, y + 1); int r = cx.R + (int)errr * 1 / 16; r = CorrectValue(r); int g = cx.G + (int)errg * 1 / 16; g = CorrectValue(g); int b = cx.B + (int)errb * 1 / 16; b = CorrectValue(b); dithering_texture.SetPixel(x + 1, y + 1, Color.FromArgb(r, g, b)); } } } }