public static bool HistoStretch(ref Bitmap graybmp, params double[] limit) { if (graybmp.PixelFormat != PixelFormat.Format8bppIndexed) return false; int w = graybmp.Width; int h = graybmp.Height; double stretchfactor = 1.00; int threshold = (int)(w * h * 0.015); if (limit.Length != 0) threshold = (int)(w * h * limit[0] / 100); int[] hist = new int[256]; BmpProc8 src = new BmpProc8(graybmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) hist[src[x, y]]++; int lt = 0; for (int i = 0; i < 256; i++) { lt += hist[i]; if (lt > threshold) { lt = i; break; } } int ht = 0; for (int i = 255; i >= 0; i--) { ht += hist[i]; if (ht > threshold) { ht = i; break; } } double originalrange = ht - lt + 1; double stretchedrange = originalrange + stretchfactor * (255 - originalrange); double scalefactor = stretchedrange / originalrange; for (int i = 0; i < 256; i++) hist[i] = AdjustByte(scalefactor * (i - lt)); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) src[x, y] = (byte)hist[src[x, y]]; src.Dispose(); return true; }
public static bool AlphaSheet(ref Bitmap bmp, bool stretch, bool bInvert) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Bitmap tmp = new Bitmap(w, h, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(tmp); g.DrawImageUnscaled(bmp, 0, 0); g.Dispose(); ImageUtility.GrayScale(ref bmp); if (stretch) ImageUtility.HistoStretch(ref bmp); BmpProc8 src = new BmpProc8(bmp); BmpProc32 dst = new BmpProc32(tmp); if (bInvert) for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) dst[x, y, eRGB.a] = (byte)(255 - src[x, y]); else for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) dst[x, y, eRGB.a] = src[x, y]; CallDispose(dst, src, bmp); bmp = tmp; return true; }
public static bool PaletteHistogram(Bitmap bmp, out Bitmap bmpHist) { if (bmp.PixelFormat != PixelFormat.Format8bppIndexed) { bmpHist = null; return false; } int w = bmp.Width; int h = bmp.Height; int[] hist = new int[256]; BmpProc8 bd = new BmpProc8(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) hist[bd[x, y]]++; bd.Dispose(); 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, 180, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(bmpHist); g.Clear(Color.AntiqueWhite); 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, 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); ColorPalette pal = bmp.Palette; for (int i = 0; i < 256; i++) { pen.Color = pal.Entries[i]; g.DrawLine(pen, 10 + i, 175, 10 + i, 158); } g.Dispose(); return true; }
public static bool Rinkaku(ref Bitmap bmp, eEdge edge, double factor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; double edg, sbl, v; double[] ff = new double[256]; for (int i = 0; i < 256; i++) ff[i] = factor * Math.Sin((double)i * Math.PI / 160d); Bitmap tmp = bmp.Clone() as Bitmap; switch (edge) { case eEdge.Edge2: Edge2(ref tmp, true); break; case eEdge.Edge3: Edge3(ref tmp, true); break; } HistoStretch(ref tmp); Contour(ref bmp, true, false); BmpProc8 src = new BmpProc8(tmp); BmpProc8 dst = new BmpProc8(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { edg = 255d - src[x, y]; sbl = 255d - dst[x, y]; v = Math.Sqrt(edg * sbl); v = v - ff[(int)v]; dst[x, y] = AdjustByte(255d - v); } 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 Gravity(ref Bitmap bmp, int period, float angle, float factor, Color dark, Color bright) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int f = (int)(period * factor); double xx, yy, ff; double angle90 = angle + 90d; double sn = Math.Sin(angle90 * Math.PI / 180d); double cs = Math.Cos(angle90 * Math.PI / 180d); Bitmap bw = bmp.Clone() as Bitmap; ImageUtility.GrayScale(ref bw); ImageUtility.HistoStretch(ref bw); Bitmap stripe = MakeGradientPattern(w + f * 2 + 2, h + f * 2 + 2, period, angle); BmpProc8 mod = new BmpProc8(bw); BmpProc24 src = new BmpProc24(stripe); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { ff = f * (255d - (double)mod[x, y]) / 255d; xx = x + ff * cs; yy = y + ff * sn; intBilinear(dst, src, x, y, xx + f + 1, yy + f + 1); } CallDispose(dst, src, mod, stripe, bw); GrayScale(ref bmp); SetTwoColorGrayPalette(bmp, dark, bright); return true; }
public static bool Invert8(ref Bitmap bmp) { if (bmp.PixelFormat != PixelFormat.Format8bppIndexed) return false; int w = bmp.Width; int h = bmp.Height; BmpProc8 src = new BmpProc8(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) src[x, y] = (byte)(255 - src[x, y]); src.Dispose(); return true; }
public static bool OrderedDither(Bitmap bmp, DitherPattern dp, ErrorDiffusion ed, bool fStretch, Color dark, Color bright, out Bitmap bmp1) { bmp1 = null; if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Bitmap tmp = (Bitmap)bmp.Clone(); ImageUtility.GrayScale(ref tmp); if (fStretch) ImageUtility.HistoStretch(ref tmp); byte[,] od22 = { { 51, 204}, {153, 102} }; byte[,] od33 = { {131, 182, 105}, {157, 236, 26}, { 79, 210, 52} }; byte[,] od332 = { { 64, 128, 64}, {128, 196, 128}, { 64, 128, 64} }; byte[,] od44 = { { 15, 195, 60, 240}, {135, 75, 180, 120}, { 45, 225, 30, 210}, {165, 105, 150, 90} }; byte[,] od442 = { { 51, 102, 204, 153}, { 204, 153, 51, 102}, { 153, 204, 102, 51}, { 102, 51, 153, 204} }; byte[,] od443 = { { 51, 102, 204, 153}, { 204, 153, 51, 102}, { 102, 51, 153, 204}, { 153, 204, 102, 51} }; byte[,] msk = od22; switch (dp) { case DitherPattern.od22: msk = od22; break; case DitherPattern.od33: msk = od33; break; case DitherPattern.od332: msk = od332; break; case DitherPattern.od44: msk = od44; break; case DitherPattern.od442: msk = od442; break; case DitherPattern.od443: msk = od443; break; } double[,] fs = { { -1, -1, 7.0/16.0}, { 3.0/16.0, 5.0/16.0, 1.0/16.0} }; double[,] st = { {-1, -1, -1, 8.0/42.0, 4.0/42.0}, {2.0/42.0, 4.0/42.0, 8.0/42.0, 4.0/42.0, 2.0/42.0}, {1.0/42.0, 2.0/42.0, 4.0/42.0, 2.0/42.0, 1.0/42.0} }; double[,] sr = { {-1, -1, -1, 5.0/32.0, 3.0/32.0}, {2.0/32.0, 4.0/32.0, 5.0/32.0, 4.0/32.0, 2.0/32.0}, {-1, 2.0/32.0, 3.0/32.0, 2.0/32.0, -1} }; double[,] jjn = { {-1, -1, -1, 7.0/48.0, 5.0/48.0}, {3.0/48.0, 5.0/48.0, 7.0/48.0, 5.0/48.0, 3.0/48.0}, {1.0/48.0, 3.0/48.0, 5.0/48.0, 3.0/48.0, 1.0/48.0} }; double[,] df = st; switch (ed) { case ErrorDiffusion.FloydSteinberg: df = fs; break; case ErrorDiffusion.Stucci: df = st; break; case ErrorDiffusion.Sierra: df = sr; break; case ErrorDiffusion.JaJuNi: df = jjn; break; } byte d8; bool d; double err; int xx, yy; int row = df.GetLength(0); int col = df.GetLength(1); int xrange = (col - 1) / 2; bmp1 = new Bitmap(w, h, PixelFormat.Format1bppIndexed); int dm = msk.GetLength(0); BmpProc8 src = new BmpProc8(tmp); BmpProc1 dst = new BmpProc1(bmp1); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { d8 = src[x, y]; d = (d8 > msk[y % dm, x % dm]); dst[x, y] = d; if (d) { err = d8 - 255; } else { err = d8; } for (int iy = 0; iy < row; iy++) for (int ix = -xrange; ix <= xrange; ix++) { xx = x + ix; if ((xx < 0) | (xx > w - 1)) continue; yy = y + iy; if (yy > h - 1) continue; if (df[iy, ix + xrange] < 0) continue; src[xx, yy] = ImageUtility.AdjustByte(src[xx, yy] + err * df[iy, ix + xrange]); } } CallDispose(dst, src, tmp); ColorPalette cp = bmp1.Palette; cp.Entries[0] = dark; cp.Entries[1] = bright; bmp1.Palette = cp; return true; }
public static bool Diacross(ref Bitmap bmp, bool bFine, Color penColor, Color bkColor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Graphics g; GrayScale(ref bmp); HistoStretch(ref bmp); Bitmap[] pattern = new Bitmap[4]; TextureBrush[] tb = new TextureBrush[4]; if (bFine) { Pen pn = new Pen(penColor, 1.8f); pn.Alignment = PenAlignment.Center; PointF[] start = { new PointF(0f, 0.5f), new PointF(0.5f, 0F), new PointF(0f, 2.5f), new PointF(2.5f, 0f) }; PointF[] stop = { new PointF(4f, 0.5f), new PointF(0.5f, 4f), new PointF(4f, 2.5f), new PointF(2.5f, 4f) }; float[] angle = { -37f, -53f }; for (int i = 0; i < 4; i++) { pattern[i] = new Bitmap(4, 4, PixelFormat.Format24bppRgb); g = Graphics.FromImage(pattern[i]); g.Clear(Color.White); g.DrawLine(pn, start[i], stop[i]); g.Dispose(); tb[i] = MakePatternBrush(pattern[i], angle[i % 2]); } pn.Dispose(); } else { Pen pn = new Pen(penColor, 2.2f); pn.Alignment = PenAlignment.Center; Point[] start = { new Point(0, 1), new Point(1, 0), new Point(0, 4), new Point(4, 0) }; Point[] stop = { new Point(9, 1), new Point(1, 9), new Point(9, 4), new Point(4, 9) }; float[] angle = { -30f, -60f }; for (int i = 0; i < 4; i++) { pattern[i] = new Bitmap(6, 6, PixelFormat.Format32bppArgb); g = Graphics.FromImage(pattern[i]); g.Clear(Color.White); g.DrawLine(pn, start[i], stop[i]); g.Dispose(); tb[i] = MakePatternBrush(pattern[i], angle[i % 2]); } pn.Dispose(); } Bitmap dst = new Bitmap(w, h, PixelFormat.Format24bppRgb); Graphics gdst = Graphics.FromImage(dst); gdst.Clear(bkColor); byte[] th = { 255, 191, 128, 64 }; Bitmap tgt; BmpProc8 mod = new BmpProc8(bmp); for (int i = 0; i < 4; i++) { tgt = new Bitmap(w, h, PixelFormat.Format32bppArgb); g = Graphics.FromImage(tgt); g.FillRectangle(tb[i], 0, 0, w, h); g.Dispose(); tb[i].Dispose(); pattern[i].Dispose(); BmpProc32 src = new BmpProc32(tgt); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (mod[x, y] < th[i]) src[x, y, eRGB.a] = AdjustByte((double)(255 - src[x, y, eRGB.r]) * ((1d - ((double)mod[x, y] / (double)th[i])))); else src[x, y, eRGB.a] = 0; } src.Dispose(); gdst.DrawImageUnscaled(tgt, 0, 0); tgt.Dispose(); } mod.Dispose(); bmp.Dispose(); gdst.Dispose(); bmp = dst; return true; }
public static bool Contour(ref Bitmap bmp, bool bStretch, bool b24bit) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Rectangle rct = new Rectangle(0, 0, w - 1, h - 1); double[] dis = new double[4]; int[] ix = new int[4]; int[] iy = new int[4]; double max; double dd = 1.732d; byte r, g, b; Bitmap tmp = new Bitmap(w, h, PixelFormat.Format8bppIndexed); SetGrayPalette(tmp); BmpProc24 src = new BmpProc24(bmp); BmpProc8 dst = new BmpProc8(tmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); r = src.R; g = src.G; b = src.B; ix[0] = x + 1; iy[0] = y - 1; // upper-right ix[1] = x + 1; iy[1] = y; // right ix[2] = x + 1; iy[2] = y + 1; // lower-right ix[3] = x; iy[3] = y + 1; // lower for (int i = 0; i < 4; i++) if (rct.Contains(ix[i], iy[i])) { src.SetXY(ix[i], iy[i]); dis[i] = (src.R - r) * (src.R - r) + (src.G - g) * (src.G - g) + (src.B - b) * (src.B - b); } else dis[i] = 0d; max = 0; for (int i = 0; i < 4; i++) if (dis[i] > max) max = dis[i]; dst[x, y] = AdjustByte(255d - Math.Sqrt(max) / dd); } CallDispose(dst, src); if (bStretch) HistoStretch(ref tmp); if (b24bit) { Graphics gr = Graphics.FromImage(bmp); gr.DrawImageUnscaled(tmp, 0, 0); gr.Dispose(); tmp.Dispose(); } else { bmp.Dispose(); bmp = tmp; } return true; }
public static bool GrayScale8(ref Bitmap bmp8) { if (bmp8.PixelFormat != PixelFormat.Format8bppIndexed) return false; int w = bmp8.Width; int h = bmp8.Height; ColorPalette pal = bmp8.Palette; byte[] cl = new byte[pal.Entries.Length]; Color c; for (int i = 0; i < pal.Entries.Length; i++) { c = pal.Entries[i]; cl[i] = (byte)(c.R * 0.299 + c.G * 0.587 + c.B * 0.114); } BmpProc8 bd = new BmpProc8(bmp8); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) bd[x, y] = cl[bd[x, y]]; bd.Dispose(); return SetGrayPalette(bmp8); }
public static bool KuwaharaGrayScale(ref Bitmap bmp, int block, bool bDetail) { if (bmp.PixelFormat != PixelFormat.Format8bppIndexed) return false; if ((block < 1) | (block > 10)) return false; int w = bmp.Width; int h = bmp.Height; int num = (block + 1) * (block + 1); int[] v = new int[4]; Point[] evP = new Point[4]; Rectangle rct = new Rectangle(0, 0, w - 1, h - 1); int[] xini = new int[4]; int[] xend = new int[4]; int[] yini = new int[4]; int[] yend = new int[4]; int d, max, min, indx; double t; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc8 src = new BmpProc8(tmp); BmpProc8 dst = new BmpProc8(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { evP[0].X = x - block; evP[0].Y = y - block; // upper-left xini[0] = x - block; xend[0] = x; yini[0] = y - block; yend[0] = y; evP[1].X = x + block; evP[1].Y = y - block; // upper-right xini[1] = x; xend[1] = x + block; yini[1] = y - block; yend[1] = y; evP[2].X = x + block; evP[2].Y = y + block; // lower-right xini[2] = x; xend[2] = x + block; yini[2] = y; yend[2] = y + block; evP[3].X = x - block; evP[3].Y = y + block; // lower-left xini[3] = x - block; xend[3] = x; yini[3] = y; yend[3] = y + block; for (int i = 0; i <= 3; i++) { v[i] = 1000; if (!rct.Contains(evP[i])) continue; max = 0; min = 255; for (int ix = xini[i]; ix <= xend[i]; ix++) for (int iy = yini[i]; iy <= yend[i]; iy++) { d = src[ix, iy]; if (d > max) max = d; if (d < min) min = d; } v[i] = max - min; } min = 1000; indx = 0; for (int i = 0; i <= 3; i++) if (v[i] < min) { min = v[i]; indx = i; } d = 0; for (int ix = xini[indx]; ix <= xend[indx]; ix++) for (int iy = yini[indx]; iy <= yend[indx]; iy++) d += src[ix, iy]; if (bDetail) { t = Math.Max(0.5d, (255d - (double)v[indx]) / 255d); dst[x, y] = ImageUtility.AdjustByte(t * (d / num) + (1d - t) * dst[x, y]); } else dst[x, y] = ImageUtility.AdjustByte(d / num); } ImageUtility.CallDispose(dst, src, tmp); return true; }
public static bool Oscillo(ref Bitmap bmp, int width, bool bHorizontal, Color dark, Color bright) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((width < 2) | (width > 10)) return false; int w = bmp.Width; int h = bmp.Height; int interval = width * 2 + 1; double sum; int count; Bitmap tmp = bmp.Clone() as Bitmap; GrayScale(ref tmp); HistoStretch(ref tmp); Pen pn = new Pen(Color.Black, 1.0f); Graphics g = Graphics.FromImage(bmp); g.Clear(Color.White); g.SmoothingMode = SmoothingMode.AntiAlias; BmpProc8 src = new BmpProc8(tmp); if (bHorizontal) for (int y = width; y < h + width; y += interval) for (int x = 0; x < w; x++) { sum = 0; count = 0; for (int iy = y - width; iy <= y + width; iy++) { if (iy > h - 1) break; count++; sum += 255 - src[x, iy]; } sum = sum * width / (count * 255d); sum = Math.Max(0.1d, sum); g.DrawLine(pn, (float)x, (float)(y + sum), (float)x, (float)(y - sum)); } else for (int x = width; x < w + width; x += interval) for (int y = 0; y < h; y++) { sum = 0; count = 0; for (int ix = x - width; ix <= x + width; ix++) { if (ix > w - 1) break; count++; sum += 255 - src[ix, y]; } sum = sum * width / (count * 255d); sum = Math.Max(0.1d, sum); g.DrawLine(pn, (float)(x - sum), (float)y, (float)(x + sum), (float)y); } src.Dispose(); g.Dispose(); GrayScale(ref bmp); SetTwoColorGrayPalette(bmp, dark, bright); return true; }
public static bool ErrorDiffusionDither(Bitmap bmp, ErrorDiffusion ed, bool fStretch, Color dark, Color bright, byte randomness, out Bitmap bmp1) { bmp1 = null; if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((randomness < 0) | (randomness > 30)) return false; int w = bmp.Width; int h = bmp.Height; Bitmap tmp = (Bitmap)bmp.Clone(); GrayScale(ref tmp); if (fStretch) HistoStretch(ref tmp); double[,] fs = { { -1, -1, 7.0/16.0}, { 3.0/16.0, 5.0/16.0, 1.0/16.0} }; double[,] st = { {-1, -1, -1, 8.0/42.0, 4.0/42.0}, {2.0/42.0, 4.0/42.0, 8.0/42.0, 4.0/42.0, 2.0/42.0}, {1.0/42.0, 2.0/42.0, 4.0/42.0, 2.0/42.0, 1.0/42.0} }; double[,] sr = { {-1, -1, -1, 5.0/32.0, 3.0/32.0}, {2.0/32.0, 4.0/32.0, 5.0/32.0, 4.0/32.0, 2.0/32.0}, {-1, 2.0/32.0, 3.0/32.0, 2.0/32.0, -1} }; double[,] jjn = { {-1, -1, -1, 7.0/48.0, 5.0/48.0}, {3.0/48.0, 5.0/48.0, 7.0/48.0, 5.0/48.0, 3.0/48.0}, {1.0/48.0, 3.0/48.0, 5.0/48.0, 3.0/48.0, 1.0/48.0} }; bmp1 = new Bitmap(w, h, PixelFormat.Format1bppIndexed); byte d8; bool d; double err; int xx, yy; byte threshold = 127; Random rnd = new Random(); byte randn = (byte)(randomness * 2 + 1); double[,] df; df = st; switch (ed) { case ErrorDiffusion.FloydSteinberg: df = fs; break; case ErrorDiffusion.Stucci: df = st; break; case ErrorDiffusion.Sierra: df = sr; break; case ErrorDiffusion.JaJuNi: df = jjn; break; } int row = df.GetLength(0); int col = df.GetLength(1); int xrange = (col - 1) / 2; BmpProc8 src = new BmpProc8(tmp); BmpProc1 dst = new BmpProc1(bmp1); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (randomness > 0) threshold = (byte)(127 + rnd.Next(randn) - randomness); d8 = src[x, y]; d = (d8 > threshold); dst[x, y] = d; if (d) { err = d8 - 255; } else { err = d8; } for (int iy = 0; iy < row; iy++) for (int ix = -xrange; ix <= xrange; ix++) { xx = x + ix; if ((xx < 0) | (xx > w - 1)) continue; yy = y + iy; if (yy > h - 1) continue; if (df[iy, ix + xrange] < 0) continue; src[xx, yy] = AdjustByte(src[xx, yy] + err * df[iy, ix + xrange]); } } CallDispose(dst, src, tmp); ColorPalette cp = bmp1.Palette; cp.Entries[0] = dark; cp.Entries[1] = bright; bmp1.Palette = cp; return true; }
public static bool Dots(Bitmap bmp, int zone, Color dark, Color bright, out Bitmap dot) { dot = null; if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 3) | (zone > 15)) return false; Bitmap tmp = bmp.Clone() as Bitmap; GrayScale(ref tmp); int w = bmp.Width; int h = bmp.Height; int count; double sum; double propc = zone / 28.5d; float cx, cy, cl, ct, cw, ch; dot = new Bitmap(w, h, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(dot); g.Clear(Color.White); g.SmoothingMode = SmoothingMode.AntiAlias; SolidBrush br = new SolidBrush(Color.Black); BmpProc8 src = new BmpProc8(tmp); for (int y = 0; y < h - 1; y += zone) for (int x = 0; x < w - 1; x += zone) { count = 0; sum = 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++; sum += 255 - src[ix, iy]; } sum = Math.Sqrt(sum / count) * propc; cx = x + (float)zone / 2f; cy = y + (float)zone / 2f; cl = (float)(cx - sum); ct = (float)(cy - sum); cw = (float)(sum * 2); ch = (float)(sum * 2); g.FillEllipse(br, cl, ct, cw, ch); } CallDispose(src, tmp); br.Dispose(); g.Dispose(); GrayScale(ref dot); SetTwoColorGrayPalette(dot, dark, bright); 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; }