public static Bitmap Operation(Bitmap bmp1, Bitmap bmp2, PIXELOPERATION po) { if (bmp1.Size != bmp2.Size) { throw new Exception("Image size not same"); } BitmapEx bex1 = BitmapEx.Begin(bmp1, ImageLockMode.ReadOnly); BitmapEx bex2 = BitmapEx.Begin(bmp2, ImageLockMode.ReadOnly); Bitmap bmp = new Bitmap(bmp1.Width, bmp1.Height, PixelFormat.Format24bppRgb); BitmapEx bex3 = BitmapEx.Begin(bmp, ImageLockMode.WriteOnly); //操作を処理する無名関数をセット ColorOperatorFunc f; switch (po) { case PIXELOPERATION.ADD: f = ((c1, c2) => { int r = c1.R + c2.R; if (r > 255) { r = 255; } int g = c1.G + c2.G; if (g > 255) { g = 255; } int b = c1.B + c2.B; if (b > 255) { b = 255; } return(Color.FromArgb(r, g, b)); }); break; case PIXELOPERATION.MUL: f = ((c1, c2) => { int r = c1.R * c2.R; if (r > 255) { r = 255; } int g = c1.G * c2.G; if (g > 255) { g = 255; } int b = c1.B * c2.B; if (b > 255) { b = 255; } return(Color.FromArgb(r, g, b)); }); break; default: throw new Exception(); } int bmpWidth = bmp1.Width; int bmpHeight = bmp1.Height; System.Threading.Tasks.Parallel.For(0, bmpHeight, y => { for (int x = 0; x < bmpWidth; x++) { bex3.SetPixel(x, y, f(bex1.GetPixel(x, y), bex2.GetPixel(x, y))); } }); bex3.End(); bex2.End(); bex1.End(); return(bmp); }
public static Bitmap Median(Bitmap bmp, int size = 3) { int adj = -size / 2; Bitmap dstBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); var pal = dstBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } dstBmp.Palette = pal; BitmapEx src = BitmapEx.Begin(bmp, ImageLockMode.ReadOnly); BitmapEx dst = BitmapEx.Begin(dstBmp, ImageLockMode.WriteOnly); int bmpWidth = bmp.Width; int bmpHeight = bmp.Height; if (bmp.PixelFormat == PixelFormat.Format8bppIndexed) { System.Threading.Tasks.Parallel.For(0, bmpHeight, i => //for (int i = 0; i < bmp.Height; i++) { byte[] brightness = new byte[size * size]; for (int j = 0; j < bmpWidth; j++) { int m = 0; for (int k = 0; k < size; k++) { int y = i + k + adj; for (int n = 0; n < size; n++) { int x = j + n + adj; if (x >= 0 && x < bmpWidth && y >= 0 && y < bmpHeight) { brightness[m++] = (byte)src.GetPixelDirect(x, y); } } } Array.Sort(brightness, 0, m); dst.SetPixelDirect(j, i, brightness[m / 2]); } }); } else { System.Threading.Tasks.Parallel.For(0, bmpHeight, i => //for (int i = 0; i < bmp.Height; i++) { byte[] brightness = new byte[size * size]; for (int j = 0; j < bmpWidth; j++) { int m = 0; for (int k = 0; k < size; k++) { int y = i + k + adj; for (int n = 0; n < size; n++) { int x = j + n + adj; if (x >= 0 && x < bmpWidth && y >= 0 && y < bmpHeight) { brightness[m++] = (byte)(src.GetPixel(x, y).GetBrightness() * 255.0F); } } } Array.Sort(brightness, 0, m); dst.SetPixelDirect(j, i, brightness[m / 2]); } }); } src.End(); dst.End(); return(dstBmp); }
private static Bitmap _filteringRGB(Bitmap bmp, float[,] ope1, float[,] ope2 = null) { int xadj = -ope1.GetLength(0) / 2; int yadj = -ope1.GetLength(1) / 2; Bitmap dstBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); var pal = dstBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } dstBmp.Palette = pal; BitmapEx src = BitmapEx.Begin(bmp, ImageLockMode.ReadOnly); BitmapEx dst = BitmapEx.Begin(dstBmp, ImageLockMode.WriteOnly); if (bmp.PixelFormat == PixelFormat.Format8bppIndexed) { throw new Exception("For RGB Bitmap only"); } else { int bmpWidth = bmp.Width; int bmpHeight = bmp.Height; System.Threading.Tasks.Parallel.For(0, bmpHeight, i => //for (int i = 0; i < bmp.Height; i++) { for (int j = 0; j < bmpWidth; j++) { float sum1B = 0, sum1G = 0, sum1R = 0; float sum2B = 0, sum2G = 0, sum2R = 0; for (int k = 0; k < ope1.GetLength(1); k++) { int y = i + k + yadj; for (int n = 0; n < ope1.GetLength(0); n++) { int x = j + n + xadj; if (x >= 0 && x < bmpWidth && y >= 0 && y < bmpHeight) { Color c = src.GetPixel(x, y); sum1B += c.B * ope1[n, k]; sum1G += c.G * ope1[n, k]; sum1R += c.R * ope1[n, k]; if (ope2 != null) { sum2B += c.B * ope2[n, k]; sum2G += c.G * ope2[n, k]; sum2R += c.R * ope2[n, k]; } } } } float sum; if (ope2 != null) { sum = (float)Math.Sqrt(sum1B * sum1B + sum1G * sum1G + sum1R * sum1R + sum2B * sum2B + sum2G * sum2G + sum2R * sum2R) / 6.0F; } else { sum = (float)Math.Sqrt(sum1B * sum1B + sum1G * sum1G + sum1R * sum1R) / 3.0F; } if (sum < 0.0F) { sum = 0.0F; } else if (sum > 255.0F) { sum = 255.0F; } dst.SetPixelDirect(j, i, (int)sum); } }); } src.End(); dst.End(); return(dstBmp); }
private static Bitmap _filteringHSV(Bitmap bmp, float[,] ope1, float[,] ope2 = null) { int xadj = -ope1.GetLength(0) / 2; int yadj = -ope1.GetLength(1) / 2; Bitmap dstBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); var pal = dstBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } dstBmp.Palette = pal; BitmapEx src = BitmapEx.Begin(bmp, ImageLockMode.ReadOnly); BitmapEx dst = BitmapEx.Begin(dstBmp, ImageLockMode.WriteOnly); if (bmp.PixelFormat == PixelFormat.Format8bppIndexed) { throw new Exception("For RGB Bitmap only"); } else { int bmpWidth = bmp.Width; int bmpHeight = bmp.Height; System.Threading.Tasks.Parallel.For(0, bmpHeight, i => //for (int i = 0; i < bmp.Height; i++) { for (int j = 0; j < bmpWidth; j++) { float sum1H = 0, sum1S = 0, sum1V = 0; float sum2H = 0, sum2S = 0, sum2V = 0; for (int k = 0; k < ope1.GetLength(1); k++) { int y = i + k + yadj; for (int n = 0; n < ope1.GetLength(0); n++) { int x = j + n + xadj; if (x >= 0 && x < bmpWidth && y >= 0 && y < bmpHeight) { Color c = src.GetPixel(x, y); float h = c.GetHue() / 360.0F; //GetHue() 0.0-360.0 float s = c.GetSaturation(); //GetSaturation() 0.0-1.0 float v = c.GetBrightness(); //GetBrightness() 0.0-1.0 sum1H += h * ope1[n, k]; sum1S += s * ope1[n, k]; sum1V += v * ope1[n, k]; if (ope2 != null) { sum2H += h * ope2[n, k]; sum2S += s * ope2[n, k]; sum2V += v * ope2[n, k]; } } } } float sum; if (ope2 != null) { sum = (float)Math.Sqrt(sum1H * sum1H + sum1S * sum1S + sum1V * sum1V + sum2H * sum2H + sum2S * sum2S + sum2V * sum2V) * 255.0F / 6.0F; } else { sum = (float)Math.Sqrt(sum1H * sum1H + sum1S * sum1S + sum1V * sum1V) * 255.0F / 3.0F; } if (sum < 0.0F) { sum = 0.0F; } else if (sum > 255.0F) { sum = 255.0F; } dst.SetPixelDirect(j, i, (int)sum); } }); } src.End(); dst.End(); return(dstBmp); }
//ope1,ope2は同じサイズであること // private static Bitmap _filtering(Bitmap bmp, float[,] ope1, float[,] ope2 = null) { int xadj = -ope1.GetLength(0) / 2; int yadj = -ope1.GetLength(1) / 2; Bitmap dstBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); var pal = dstBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } dstBmp.Palette = pal; BitmapEx src = BitmapEx.Begin(bmp, ImageLockMode.ReadOnly); BitmapEx dst = BitmapEx.Begin(dstBmp, ImageLockMode.WriteOnly); int bmpWidth = bmp.Width; int bmpHeight = bmp.Height; if (bmp.PixelFormat == PixelFormat.Format8bppIndexed) { System.Threading.Tasks.Parallel.For(0, bmpHeight, i => //for (int i = 0; i < bmp.Height; i++) { for (int j = 0; j < bmpWidth; j++) { float sum1 = 0, sum2 = 0; for (int k = 0; k < ope1.GetLength(1); k++) { int y = i + k + yadj; for (int n = 0; n < ope1.GetLength(0); n++) { int x = j + n + xadj; if (x >= 0 && x < bmpWidth && y >= 0 && y < bmpHeight) { int d = src.GetPixelDirect(x, y); sum1 += d * ope1[n, k]; if (ope2 != null) { sum2 += d * ope2[n, k]; } } } } if (ope2 != null) { sum1 = (float)Math.Sqrt(sum1 * sum1 + sum2 * sum2) / 2.0F; } if (sum1 < 0.0F) { sum1 = 0.0F; } else if (sum1 > 255.0F) { sum1 = 255.0F; } dst.SetPixelDirect(j, i, (int)sum1); } }); } else { System.Threading.Tasks.Parallel.For(0, bmpHeight, i => //for (int i = 0; i < bmp.Height; i++) { for (int j = 0; j < bmpWidth; j++) { float sum1 = 0, sum2 = 0; for (int k = 0; k < ope1.GetLength(1); k++) { int y = i + k + yadj; for (int n = 0; n < ope1.GetLength(0); n++) { int x = j + n + xadj; if (x >= 0 && x < bmpWidth && y >= 0 && y < bmpHeight) { float br = src.GetPixel(x, y).GetBrightness() * 255.0F; sum1 += br * ope1[n, k]; if (ope2 != null) { sum2 += br * ope2[n, k]; } } } } if (ope2 != null) { sum1 = (float)Math.Sqrt(sum1 * sum1 + sum2 * sum2) / 2.0F; } if (sum1 < 0.0F) { sum1 = 0.0F; } else if (sum1 > 255.0F) { sum1 = 255.0F; } dst.SetPixelDirect(j, i, (int)sum1); } }); } src.End(); dst.End(); return(dstBmp); }