public static bool GaussianBlur(ref Bitmap bmp, int zone) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 1) | (zone > 30)) return false; int w = bmp.Width; int h = bmp.Height; int range = zone * 3; double[] gf = new double[range + 1]; for (int i = 0; i <= range; i++) gf[i] = Math.Exp(-i * i / (2 * zone * zone)); double count, sr, sg, sb, gauss; int ir; Bitmap tmp = (Bitmap)bmp.Clone(); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); // dst --> src x-direction average for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { count = sr = sg = sb = 0; for (int ix = x - range; ix <= x + range; ix++) { if ((ix < 0) | (ix > w - 1)) continue; ir = dst.IndexR(ix, y); gauss = gf[Math.Abs(ix - x)]; sr += dst[ir] * gauss; sg += dst[ir - 1] * gauss; sb += dst[ir - 2] * gauss; count += gauss; } ir = src.IndexR(x, y); src[ir] = AdjustByte(sr / count); src[ir - 1] = AdjustByte(sg / count); src[ir - 2] = AdjustByte(sb / count); } // src --> dst y-direction average for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { count = sr = sg = sb = 0; for (int iy = y - range; iy <= y + range; iy++) { if ((iy < 0) | (iy > h - 1)) continue; ir = src.IndexR(x, iy); gauss = gf[Math.Abs(iy - y)]; sr += src[ir] * gauss; sg += src[ir - 1] * gauss; sb += src[ir - 2] * gauss; count += gauss; } ir = dst.IndexR(x, y); dst[ir] = AdjustByte(sr / count); dst[ir - 1] = AdjustByte(sg / count); dst[ir - 2] = AdjustByte(sb / count); } CallDispose(dst, src, tmp); return true; }
public static int CountColors(Bitmap bmp) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return -1; int w = bmp.Width; int h = bmp.Height; int num = w * h; int[] colors = new int[num]; int indx = 0; int ir; BmpProc24 src = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { ir = src.IndexR(x, y); colors[indx] = (int)((((src[ir] << 8) | src[ir - 1]) << 8) | src[ir - 2]); indx++; } src.Dispose(); Array.Sort(colors); int count = 1; for (int i = 1; i < num; i++) if (colors[i - 1] != colors[i]) count++; return count; }
public static bool BrightnessHistogram(this Bitmap self, out Bitmap bmpHist) { if (self == null) throw new ArgumentNullException("self is null."); if (self.PixelFormat != PixelFormat.Format24bppRgb) { bmpHist = null; return false; } int w = self.Width; int h = self.Height; int[] hist = new int[256]; hist.Initialize(); int ir, indx; using (BmpProc24 bd = new BmpProc24(self)) { for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { ir = bd.IndexR(x, y); indx = (int)(bd[ir] * 0.299 + bd[ir - 1] * 0.587 + bd[ir - 2] * 0.114); hist[indx]++; } } int max = -1; for (int i = 0; i < 256; i++) if (hist[i] > max) max = hist[i]; for (int i = 0; i < 256; i++) hist[i] = hist[i] * 140 / max; bmpHist = new Bitmap(275, 160, PixelFormat.Format24bppRgb); using (Graphics g = Graphics.FromImage(bmpHist)) { g.Clear(Color.AntiqueWhite); using (Pen pen = new Pen(Color.Gray, 1F)) { for (int i = 0; i < 256; i++) g.DrawLine(pen, 10 + i, 150, 10 + i, 150 - hist[i]); pen.Color = Color.Black; g.DrawLine(pen, 10, 150, 10, 10); for (int i = 0; i <= 20; i++) if ((i % 2) == 0) g.DrawLine(pen, 10, 150 - 7 * i, 6, 150 - 7 * i); else g.DrawLine(pen, 10, 150 - 7 * i, 8, 150 - 7 * i); g.DrawLine(pen, 10, 150, 10 + 255, 150); for (int i = 0; i <= 51; i++) if ((i % 2) == 0) g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 154); else g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 152); } } return true; }
public static bool ConvolutionCore(ref Bitmap bmp, int[,] mask, double divfactor, double offset) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int row = mask.GetLength(0); int col = mask.GetLength(1); int xzone = (row - 1) / 2; int yzone = (col - 1) / 2; int ix, iy, xx, yy, mx, my; Bitmap tmp = (Bitmap)(bmp.Clone()); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); { int r, g, b; int srcR, dstR; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { r = g = b = 0; for (iy = y - yzone; iy <= y + yzone; iy++) { for (ix = x - xzone; ix <= x + xzone; ix++) { mx = ix - x + xzone; my = iy - y + yzone; if (mask[mx, my] == 0) continue; xx = ix; yy = iy; if ((iy < 0) || (iy > h - 1)) yy = y; if ((ix < 0) || (ix > w - 1)) xx = x; srcR = src.IndexR(xx, yy); r += src[srcR] * mask[mx, my]; g += src[srcR - 1] * mask[mx, my]; b += src[srcR - 2] * mask[mx, my]; } } dstR = dst.IndexR(x, y); dst[dstR] = AdjustByte((double)r / divfactor + offset); dst[dstR - 1] = AdjustByte((double)g / divfactor + offset); dst[dstR - 2] = AdjustByte((double)b / divfactor + offset); } } } CallDispose(dst, src, tmp); return true; }
public static bool TwoColorGrayScale(ref Bitmap bmp, Color Dark, Color Bright) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Bitmap tmp = new Bitmap(w, h, PixelFormat.Format8bppIndexed); if (!SetTwoColorGrayPalette(tmp, Dark, Bright)) { tmp.Dispose(); return false; } BmpProc24 src = new BmpProc24(bmp); BmpProc8 dst = new BmpProc8(tmp); int ir; for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { ir = src.IndexR(x, y); dst[x, y] = (byte)(src[ir] * 0.299 + src[ir - 1] * 0.587 + src[ir - 2] * 0.114); } CallDispose(dst, src, bmp); bmp = tmp; return true; }
public static bool TwoValued1(Bitmap bmp24, int threshold, out Bitmap bmp1) { bmp1 = null; if (bmp24.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp24.Width; int h = bmp24.Height; bmp1 = new Bitmap(w, h, PixelFormat.Format1bppIndexed); int srcR; BmpProc24 src = new BmpProc24(bmp24); BmpProc1 dst = new BmpProc1(bmp1); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { srcR = src.IndexR(x, y); // current dst[x, y] = ((src[srcR] * 0.299 + src[srcR - 1] * 0.587 + src[srcR - 2] * 0.114) > threshold); } CallDispose(dst, src); return true; }
public static bool TwoValued2(Bitmap bmp24, Color BKcolor, out Bitmap bmp1) { bmp1 = null; if (bmp24.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp24.Width; int h = bmp24.Height; byte r = BKcolor.R; byte g = BKcolor.G; byte b = BKcolor.B; bmp1 = new Bitmap(w, h, PixelFormat.Format1bppIndexed); int ir; BmpProc24 src = new BmpProc24(bmp24); BmpProc1 dst = new BmpProc1(bmp1); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { ir = src.IndexR(x, y); // current dst[x, y] = ((src[ir] == r) && (src[ir - 1] == g) && (src[ir - 2] == b)); } CallDispose(dst, src); return true; }
public static bool GrayScale(ref Bitmap bmp) { if (bmp == null) throw new ArgumentNullException("bmp is null."); if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Bitmap tmp = new Bitmap(w, h, PixelFormat.Format8bppIndexed); if (!SetGrayPalette(tmp)) { tmp.Dispose(); return false; } int srcR; BmpProc24 src = new BmpProc24(bmp); BmpProc8 dst = new BmpProc8(tmp); for (int y = 0; y < h; ++y) for (int x = 0; x < w; ++x) { srcR = src.IndexR(x, y); // current dst[x, y] = (byte)(src[srcR] * 0.299 + src[srcR - 1] * 0.587 + src[srcR - 2] * 0.114); } CallDispose(dst, src, bmp); bmp = tmp; return true; }
public static bool P2PCore(ref Bitmap bmp, P2PFunc func, params double[] param) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; byte r, g, b; int ir; BmpProc24 bd = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { ir = bd.IndexR(x, y); r = bd[ir]; g = bd[ir - 1]; b = bd[ir - 2]; func(ref r, ref g, ref b, param); bd[ir] = r; bd[ir - 1] = g; bd[ir - 2] = b; } bd.Dispose(); return true; }
public static bool Mosaic(ref Bitmap bmp, int zone, Rectangle rct) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 2) | (zone > 30)) return false; int w = bmp.Width; int h = bmp.Height; int ir, count, sumr, sumg, sumb; BmpProc24 src = new BmpProc24(bmp); for (int y = rct.Y; y < rct.Y + rct.Height; y += zone) { if ((y < 0) | (y > h - 1)) continue; for (int x = rct.X; x < rct.X + rct.Width; x += zone) { if ((x < 0) | (x > w - 1)) continue; count = sumr = sumg = sumb = 0; for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((iy > h - 1) | (ix > w - 1)) continue; if ((iy > rct.Y + rct.Height - 1) | (ix > rct.X + rct.Width - 1)) continue; count++; ir = src.IndexR(ix, iy); sumr += src[ir]; sumg += src[ir - 1]; sumb += src[ir - 2]; } sumr = sumr / count; sumg = sumg / count; sumb = sumb / count; for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((iy > h - 1) | (ix > w - 1)) continue; if ((iy > rct.Y + rct.Height - 1) | (ix > rct.X + rct.Width - 1)) continue; ir = src.IndexR(ix, iy); src[ir] = (byte)sumr; src[ir - 1] = (byte)sumg; src[ir - 2] = (byte)sumb; } } } src.Dispose(); return true; }
public static bool Sharpen(ref Bitmap bmp, int percent) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Bitmap tmp = (Bitmap)(bmp.Clone()); Edge(ref tmp, false); double f = (double)(percent) / 100; int ird, irs; BmpProc24 dst = new BmpProc24(bmp); BmpProc24 src = new BmpProc24(tmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { ird = dst.IndexR(x, y); irs = src.IndexR(x, y); dst[ird] = AdjustByte(dst[ird] + (src[irs] - 127) * f); dst[ird - 1] = AdjustByte(dst[ird - 1] + (src[irs - 1] - 127) * f); dst[ird - 2] = AdjustByte(dst[ird - 2] + (src[irs - 2] - 127) * f); } CallDispose(src, dst, tmp); return true; }
public static bool RGBHistogram(Bitmap bmp, out Bitmap bmpHist) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) { bmpHist = null; return false; } int w = bmp.Width; int h = bmp.Height; int[] hist = new int[256]; int[] rh = new int[256]; int[] gh = new int[256]; int[] bh = new int[256]; int ir, indx; BmpProc24 bd = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { ir = bd.IndexR(x, y); rh[bd[ir]]++; gh[bd[ir - 1]]++; bh[bd[ir - 2]]++; indx = (int)(bd[ir] * 0.299 + bd[ir - 1] * 0.587 + bd[ir - 2] * 0.114); hist[indx]++; } bd.Dispose(); int max = -1; for (int i = 0; i < 256; i++) { if (rh[i] > max) max = rh[i]; if (gh[i] > max) max = gh[i]; if (bh[i] > max) max = bh[i]; if (hist[i] > max) max = hist[i]; } PointF[] pt = new PointF[256]; bmpHist = new Bitmap(275, 160, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(bmpHist); g.SmoothingMode = SmoothingMode.AntiAlias; g.Clear(Color.AntiqueWhite); Pen pen = new Pen(Color.Red, 1.5F); for (int i = 0; i < 256; i++) { pt[i].X = 10 + i; pt[i].Y = (float)(150 - rh[i] * 140f / max); } g.DrawLines(pen, pt); pen.Color = Color.ForestGreen; for (int i = 0; i < 256; i++) pt[i].Y = (float)(150 - gh[i] * 140f / max); g.DrawLines(pen, pt); pen.Color = Color.Blue; for (int i = 0; i < 256; i++) pt[i].Y = (float)(150 - bh[i] * 140f / max); g.DrawLines(pen, pt); pen.Color = Color.Black; for (int i = 0; i < 256; i++) pt[i].Y = (float)(150 - hist[i] * 140f / max); g.DrawLines(pen, pt); pen.Color = Color.Black; g.DrawLine(pen, 8, 150, 8, 10); for (int i = 0; i <= 20; i++) if ((i % 2) == 0) g.DrawLine(pen, 8, 150 - 7 * i, 4, 150 - 7 * i); else g.DrawLine(pen, 8, 150 - 7 * i, 6, 150 - 7 * i); g.DrawLine(pen, 10, 150, 10 + 255, 150); for (int i = 0; i <= 51; i++) if ((i % 2) == 0) g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 154); else g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 152); g.Dispose(); return true; }
public static bool Pixelate3(ref Bitmap bmp, int zone) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 2) | (zone > 30)) return false; int w = bmp.Width; int h = bmp.Height; int ir, count, sumr, sumg, sumb; byte[,] rr = new byte[w / zone + 1, h / zone + 1]; byte[,] gg = new byte[w / zone + 1, h / zone + 1]; byte[,] bb = new byte[w / zone + 1, h / zone + 1]; int countX, countY; byte rrr, ggg, bbb; countY = 0; BmpProc24 src = new BmpProc24(bmp); for (int y = 0; y < h; y += zone) { countX = 0; for (int x = 0; x < w; x += zone) { count = sumr = sumg = sumb = 0; for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((iy > h - 1) | (ix > w - 1)) continue; count++; ir = src.IndexR(ix, iy); sumr += src[ir]; sumg += src[ir - 1]; sumb += src[ir - 2]; } sumr = sumr / count; sumg = sumg / count; sumb = sumb / count; rr[countX, countY] = (byte)sumr; gg[countX, countY] = (byte)sumg; bb[countX, countY] = (byte)sumb; rrr = (byte)sumr; ggg = (byte)sumg; bbb = (byte)sumb; if ((sumr < 230) & (sumr > 15)) { rrr = (byte)(sumr - 15); } if ((sumg < 230) & (sumg > 15)) { ggg = (byte)(sumg - 15); } if ((sumb < 230) & (sumb > 15)) { bbb = (byte)(sumb - 15); } for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((iy > h - 1) | (ix > w - 1)) continue; ir = src.IndexR(ix, iy); src[ir] = rrr; src[ir - 1] = ggg; src[ir - 2] = bbb; } countX++; } countY++; } src.Dispose(); countY = 0; SolidBrush br = new SolidBrush(Color.Black); Point[] pt = new Point[3]; Graphics g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.AntiAlias; for (int y = 0; y < h; y += zone) { countX = 0; for (int x = 0; x < w; x += zone) { rrr = rr[countX, countY]; ggg = gg[countX, countY]; bbb = bb[countX, countY]; if ((rrr < 230) & (rrr > 15)) { rrr = (byte)(rrr + 15); } if ((ggg < 230) & (ggg > 15)) { ggg = (byte)(ggg + 15); } if ((bbb < 230) & (bbb > 15)) { bbb = (byte)(bbb + 15); } br.Color = Color.FromArgb(rrr, ggg, bbb); pt[0].X = x; pt[0].Y = y; pt[1].X = x + zone; pt[1].Y = y; pt[2].X = x; pt[2].Y = y + zone; g.FillPolygon(br, pt); countX++; } countY++; } g.Dispose(); br.Dispose(); return true; }
public static bool Pixelate2(ref Bitmap bmp, int zone) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 2) | (zone > 30)) return false; int w = bmp.Width; int h = bmp.Height; int ir, count, sumr, sumg, sumb; byte[,] rr = new byte[w / zone + 1, h / zone + 1]; byte[,] gg = new byte[w / zone + 1, h / zone + 1]; byte[,] bb = new byte[w / zone + 1, h / zone + 1]; int countX, countY; byte rrr, ggg, bbb; countY = 0; BmpProc24 src = new BmpProc24(bmp); for (int y = 0; y < h; y += zone) { countX = 0; for (int x = 0; x < w; x += zone) { count = sumr = sumg = sumb = 0; for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((iy > h - 1) | (ix > w - 1)) continue; count++; ir = src.IndexR(ix, iy); sumr += src[ir]; sumg += src[ir - 1]; sumb += src[ir - 2]; } sumr = sumr / count; sumg = sumg / count; sumb = sumb / count; rr[countX, countY] = (byte)sumr; gg[countX, countY] = (byte)sumg; bb[countX, countY] = (byte)sumb; if (sumr > 127) { rrr = (byte)(sumr * 0.8); } else { rrr = (byte)(sumr * 1.2); } if (sumg > 127) { ggg = (byte)(sumg * 0.8); } else { ggg = (byte)(sumg * 1.2); } if (sumb > 127) { bbb = (byte)(sumb * 0.8); } else { bbb = (byte)(sumb * 1.2); } for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((iy > h - 1) | (ix > w - 1)) continue; ir = src.IndexR(ix, iy); src[ir] = rrr; src[ir - 1] = ggg; src[ir - 2] = bbb; } countX++; } countY++; } src.Dispose(); countY = 0; SolidBrush br = new SolidBrush(Color.Black); Rectangle rct = new Rectangle(0, 0, zone, zone); Graphics g = Graphics.FromImage(bmp); g.SmoothingMode = SmoothingMode.AntiAlias; for (int y = 0; y < h; y += zone) { countX = 0; for (int x = 0; x < w; x += zone) { br.Color = Color.FromArgb(rr[countX, countY], gg[countX, countY], bb[countX, countY]); rct.X = x; rct.Y = y; g.FillEllipse(br, rct); countX++; } countY++; } g.Dispose(); br.Dispose(); return true; }