public static bool PhotoBlur(ref Bitmap bmp, int zone, int baseOffset) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 1) | (zone > 30)) return false; if ((baseOffset < 0) | (baseOffset > 20)) return false; int w = bmp.Width; int h = bmp.Height; double baseB = 1.010d + (double)baseOffset / 1000d; double[] paw = new double[256]; for (int i = 0; i < 256; i++) paw[i] = Math.Pow(baseB, (double)i); int[,] mask = new int[zone * 2 + 1, zone * 2 + 1]; int r = zone * zone; for (int i = 0; i < zone * 2 + 1; i++) for (int j = 0; j < zone * 2 + 1; j++) if ((i - zone) * (i - zone) + (j - zone) * (j - zone) <= r) mask[i, j] = 1; else mask[i, j] = 0; double rr, gg, bb; int count; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { count = 0; rr = gg = bb = 0d; for (int iy = y - zone; iy < y + zone + 1; iy++) for (int ix = x - zone; ix < x + zone + 1; ix++) { if ((iy < 0) | (iy > h - 1)) continue; if ((ix < 0) | (ix > w - 1)) continue; src.SetXY(ix, iy); rr += paw[src.R] * mask[ix - x + zone, iy - y + zone]; gg += paw[src.G] * mask[ix - x + zone, iy - y + zone]; bb += paw[src.B] * mask[ix - x + zone, iy - y + zone]; count += mask[ix - x + zone, iy - y + zone]; } dst.SetXY(x, y); dst.R = AdjustByte(Math.Log(rr / count, baseB)); dst.G = AdjustByte(Math.Log(gg / count, baseB)); dst.B = AdjustByte(Math.Log(bb / count, baseB)); } CallDispose(dst, src, tmp); return true; }
public static bool AdditiveColor(Bitmap bmpDst, Bitmap bmpSrc, RGBSelection rgb) { if (bmpDst.PixelFormat != PixelFormat.Format24bppRgb) return false; if (bmpSrc.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmpDst.Width; int h = bmpDst.Height; if ((bmpSrc.Width != w) | (bmpSrc.Height != h)) return false; BmpProc24 src = new BmpProc24(bmpSrc); BmpProc24 dst = new BmpProc24(bmpDst); switch (rgb) { case RGBSelection.all: for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); dst.SetXY(x, y); dst.R = AdjustByte(dst.R + src.R); dst.G = AdjustByte(dst.G + src.G); dst.B = AdjustByte(dst.B + src.B); } break; case RGBSelection.red: for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); dst.SetXY(x, y); dst.R = AdjustByte(dst.R + src.R); } break; case RGBSelection.green: for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); dst.SetXY(x, y); dst.G = AdjustByte(dst.G + src.G); } break; case RGBSelection.blue: for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); dst.SetXY(x, y); dst.B = AdjustByte(dst.B + src.B); } break; } CallDispose(dst, src); return true; }
public static bool CircularPixelate(ref Bitmap bmp, int rzone, int azone, int cx, int cy) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; pixelinfo[,] pi = new pixelinfo[w, h]; if ((cx == 0) & (cy == 0)) { cx = w / 2; cy = h / 2; } double degree = 180d / Math.PI; double r, a; int xx, yy; Rectangle rct = new Rectangle(0, 0, w - 1, h - 1); Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { r = Math.Sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)); a = Math.Atan2(y - cy, x - cx) * degree; // degree r = ((int)(r + 0.5) / rzone) * rzone; a = ((int)(a + 0.5) / azone) * azone / degree; // radian xx = (int)(r * Math.Cos(a) + cx); yy = (int)(r * Math.Sin(a) + cy); if (rct.Contains(xx, yy)) { src.SetXY(x, y); pi[xx, yy].r += src.R; pi[xx, yy].g += src.G; pi[xx, yy].b += src.B; pi[xx, yy].count += 1; } } for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if (pi[x, y].count == 0) continue; src.SetXY(x, y); src.R = (byte)(pi[x, y].r / pi[x, y].count); src.G = (byte)(pi[x, y].g / pi[x, y].count); src.B = (byte)(pi[x, y].b / pi[x, y].count); } for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { r = Math.Sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)); a = Math.Atan2(y - cy, x - cx) * degree; // degree r = ((int)(r + 0.5) / rzone) * rzone; a = ((int)(a + 0.5) / azone) * azone / degree; // radian xx = (int)(r * Math.Cos(a) + cx); yy = (int)(r * Math.Sin(a) + cy); if (rct.Contains(xx, yy)) { dst.SetXY(x, y); src.SetXY(xx, yy); dst.R = src.R; dst.G = src.G; dst.B = src.B; } } CallDispose(dst, src, tmp); return true; }
public static bool PatternMosaic(ref Bitmap bmp, PatternShape ps, int width, int height) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((width < 5) | (width > 20)) return false; if ((height < 5) | (height > 60)) return false; int w = bmp.Width; int h = bmp.Height; double ww = (double)width; double hh = (double)height; double[] wd = new double[height]; int[] iwd = new int[height]; switch (ps) { case PatternShape.Brick: for (int i = 0; i < height; i++) { if ((double)i < (hh / 2d)) wd[i] = ww; else wd[i] = 0; iwd[i] = (int)(wd[i] + 0.5); } break; case PatternShape.Diamond: for (int i = 0; i < height; i++) { if ((double)i < (hh / 2d)) wd[i] = ww * (double)i * 2d / hh; else wd[i] = ww * 2d - ww * (double)i * 2d / hh; iwd[i] = (int)(wd[i] + 0.5); } break; case PatternShape.Hexagon: for (int i = 0; i < height; i++) { if ((double)i < (hh / 6d)) wd[i] = ww * (double)i * 6d / hh; else { if ((double)i < (hh / 2d)) wd[i] = ww; else { if ((double)i < (hh * 2d / 3d)) wd[i] = ww * 4d - ww * (double)i * 6d / hh; else wd[i] = 0; } } iwd[i] = (int)(wd[i] + 0.5); } break; case PatternShape.Circle: for (int i = 0; i < height; i++) { if ((double)i < (hh / 2d)) wd[i] = ww * (double)i * 2d / hh - (ww / 8d) * Math.Sin((double)i * 4d / hh * Math.PI); else wd[i] = ww * 2d - ww * (double)i * 2d / hh + (ww / 8d) * Math.Sin((double)(i - hh / 2d) * 4d / hh * Math.PI); iwd[i] = (int)(wd[i] + 0.5); } break; } bool eflag = false; int r, g, b, count, d, im, yinit; double rm; Bitmap tmp = bmp.Clone() as Bitmap; Graphics gr = Graphics.FromImage(bmp); gr.SmoothingMode = SmoothingMode.AntiAlias; Pen pn = new Pen(Color.Black, 1.0f); BmpProc24 src = new BmpProc24(tmp); for (int x = 0; x < w - 1 + width; x += width) { eflag = !eflag; if (eflag) yinit = 0; else yinit = -height / 2; for (int y = yinit; y < h - 1; y += height) { r = g = b = count = 0; for (int iy = y; iy < y + height; iy++) { if ((iy > h - 1) | (iy < 0)) continue; d = iy % height; if (eflag) { im = iwd[d]; rm = wd[d]; } else { im = width - iwd[d]; rm = ww - wd[d]; } for (int ix = x - im; ix <= x + im; ix++) { if ((ix < 0) | (ix > w - 1)) continue; src.SetXY(ix, iy); r += src.R; g += src.G; b += src.B; count++; } } if (count == 0) continue; r /= count; g /= count; b /= count; pn.Color = Color.FromArgb(r, g, b); for (int iy = y; iy < y + height; iy++) { if ((iy > h - 1) | (iy < 0)) continue; d = iy % height; if (eflag) { im = iwd[d]; rm = wd[d]; } else { im = width - iwd[d]; rm = (double)width - wd[d]; } gr.DrawLine(pn, (float)(x - rm), (float)iy, (float)(x + rm), (float)iy); } } } CallDispose(src, gr, tmp); return true; }
public static bool AdditiveColor(Bitmap bmpDst, Bitmap bmpSrc, RGBSelection rgb, int dstX, int dstY) { if (bmpDst.PixelFormat != PixelFormat.Format24bppRgb) return false; if (bmpSrc.PixelFormat != PixelFormat.Format24bppRgb) return false; Rectangle dstRect = new Rectangle(0, 0, bmpDst.Width, bmpDst.Height); Rectangle srcRect = new Rectangle(dstX, dstY, bmpSrc.Width, bmpSrc.Height); if (!dstRect.IntersectsWith(srcRect)) return true; dstRect.Intersect(srcRect); int scanX = dstRect.X; int scanY = dstRect.Y; int scanEndX = scanX + dstRect.Width; int scanEndY = scanY + dstRect.Height; BmpProc24 src = new BmpProc24(bmpSrc); BmpProc24 dst = new BmpProc24(bmpDst); switch (rgb) { case RGBSelection.all: for (int y = scanY; y < scanEndY; y++) for (int x = scanX; x < scanEndX; x++) { src.SetXY(x - dstX, y - dstY); dst.SetXY(x, y); dst.R = AdjustByte(dst.R + src.R); dst.G = AdjustByte(dst.G + src.G); dst.B = AdjustByte(dst.B + src.B); } break; case RGBSelection.red: for (int y = scanY; y < scanEndY; y++) for (int x = scanX; x < scanEndX; x++) { src.SetXY(x - dstX, y - dstY); dst.SetXY(x, y); dst.R = AdjustByte(dst.R + src.R); } break; case RGBSelection.green: for (int y = scanY; y < scanEndY; y++) for (int x = scanX; x < scanEndX; x++) { src.SetXY(x - dstX, y - dstY); dst.SetXY(x, y); dst.G = AdjustByte(dst.G + src.G); } break; case RGBSelection.blue: for (int y = scanY; y < scanEndY; y++) for (int x = scanX; x < scanEndX; x++) { src.SetXY(x - dstX, y - dstY); dst.SetXY(x, y); dst.B = AdjustByte(dst.B + src.B); } break; } CallDispose(dst, src); return true; }
public static bool UnsharpMask(ref Bitmap bmp, int zone, int percent) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 0) | (zone > 15)) return false; if (percent < 0) return false; int w = bmp.Width; int h = bmp.Height; double f = (double)percent / 100d; Bitmap tmp = bmp.Clone() as Bitmap; GaussianBlur(ref tmp, zone); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h - 1; y++) for (int x = 0; x < w - 1; x++) { src.SetXY(x, y); dst.SetXY(x, y); dst.R = AdjustByte(dst.R + f * (dst.R - src.R)); dst.G = AdjustByte(dst.G + f * (dst.G - src.G)); dst.B = AdjustByte(dst.B + f * (dst.B - src.B)); } CallDispose(dst, src, tmp); return true; }
public static bool KuwaharaMedian(ref Bitmap bmp, int block) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) 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 iarr, maxr, maxg, maxb, minr, ming, minb, indx, min; byte[] rr = new byte[num]; byte[] gg = new byte[num]; byte[] bb = new byte[num]; int imed = num / 2; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(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; maxr = maxg = maxb = 0; minr = ming = minb = 255; for (int ix = xini[i]; ix <= xend[i]; ix++) for (int iy = yini[i]; iy <= yend[i]; iy++) { src.SetXY(ix, iy); if (src.R > maxr) maxr = src.R; if (src.R < minr) minr = src.R; if (src.G > maxg) maxg = src.G; if (src.G < ming) ming = src.G; if (src.B > maxb) maxb = src.B; if (src.B < minb) minb = src.B; } v[i] = (maxr - minr) + (maxg - ming) + (maxb - minb); } min = 1000; indx = 0; for (int i = 0; i <= 3; i++) if (v[i] < min) { min = v[i]; indx = i; } iarr = 0; for (int ix = xini[indx]; ix <= xend[indx]; ix++) for (int iy = yini[indx]; iy <= yend[indx]; iy++) { src.SetXY(ix, iy); rr[iarr] = src.R; gg[iarr] = src.G; bb[iarr] = src.B; iarr++; } Array.Sort(rr); Array.Sort(gg); Array.Sort(bb); dst.SetXY(x, y); dst.R = rr[imed]; dst.G = gg[imed]; dst.B = bb[imed]; } CallDispose(dst, src, tmp); return true; }
public static bool SaturationHistogram(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 hue, satu, lumi; byte rr, gg, bb; BmpProc24 src = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); rr = src.R; gg = src.G; bb = src.B; ImageUtils.RGBToHSL(rr, gg, bb, out hue, out satu, out lumi); hist[satu]++; } src.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, 160, 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 % 10) == 0) g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 156); else if ((i % 5) == 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 void intNearest(BmpProc24 dst, BmpProc24 src, int dstX, int dstY, double srcX, double srcY) { int ix = (int)(srcX + 0.5); // nearest point int iy = (int)(srcY + 0.5); dst.SetXY(dstX, dstY); src.SetXY(ix, iy); dst.R = src.R; dst.G = src.G; dst.B = src.B; }
public static bool KuwaharaDetail(ref Bitmap bmp, int block) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) 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[] vr = new int[4]; int[] vg = new int[4]; int[] vb = new int[4]; int r, g, b, maxr, maxg, maxb, minr, ming, minb, indx, min; double t; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(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; maxr = maxg = maxb = 0; minr = ming = minb = 255; for (int ix = xini[i]; ix <= xend[i]; ix++) for (int iy = yini[i]; iy <= yend[i]; iy++) { src.SetXY(ix, iy); if (src.R > maxr) maxr = src.R; if (src.R < minr) minr = src.R; if (src.G > maxg) maxg = src.G; if (src.G < ming) ming = src.G; if (src.B > maxb) maxb = src.B; if (src.B < minb) minb = src.B; } vr[i] = maxr - minr; vg[i] = maxg - ming; vb[i] = maxb - minb; v[i] = vr[i] + vg[i] + vb[i]; } min = 1000; indx = 0; for (int i = 0; i <= 3; i++) if (v[i] < min) { min = v[i]; indx = i; } r = g = b = 0; for (int ix = xini[indx]; ix <= xend[indx]; ix++) for (int iy = yini[indx]; iy <= yend[indx]; iy++) { src.SetXY(ix, iy); r += src.R; g += src.G; b += src.B; } dst.SetXY(x, y); t = Math.Max(0.6d, (255d - (double)vr[indx]) / 255d); dst.R = AdjustByte(t * (r / num) + (1d - t) * dst.R); t = Math.Max(0.6d, (255d - (double)vg[indx]) / 255d); dst.G = AdjustByte(t * (g / num) + (1d - t) * dst.G); t = Math.Max(0.6d, (255d - (double)vb[indx]) / 255d); dst.B = AdjustByte(t * (b / num) + (1d - t) * dst.B); } CallDispose(dst, src, tmp); return true; }
public static bool HistoStretch24(ref Bitmap bmp, params double[] limit) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; double stretchfactor = 1.00; int threshold = (int)(w * h * 0.015); if (limit.Length != 0) threshold = (int)(w * h * limit[0] / 100); int hue, sat, lum, lt, ht; byte rr, gg, bb; double originalrange, stretchedrange, scalefactor; int[] hist = new int[256]; BmpProc24 src = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); RGBToHSL(src.R, src.G, src.B, out hue, out sat, out lum); hist[lum]++; } lt = 0; for (int i = 0; i < 256; i++) { lt += hist[i]; if (lt > threshold) { lt = i; break; } } ht = 0; for (int i = 255; i >= 0; i--) { ht += hist[i]; if (ht > threshold) { ht = i; break; } } originalrange = ht - lt + 1; stretchedrange = originalrange + stretchfactor * (255 - originalrange); 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.SetXY(x, y); RGBToHSL(src.R, src.G, src.B, out hue, out sat, out lum); lum = hist[lum]; HSLToRGB(hue, sat, lum, out rr, out gg, out bb); src.R = rr; src.G = gg; src.B = bb; } src.Dispose(); return true; }
public static bool DrawFramedAlpha(Bitmap dstBmp, Bitmap srcBmp, int dstX, int dstY) { if (dstBmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if (srcBmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int dw = dstBmp.Width; int dh = dstBmp.Height; int sw = srcBmp.Width; int sh = srcBmp.Height; double pi = Math.PI; double f; BmpProc24 dst = new BmpProc24(dstBmp); BmpProc24 src = new BmpProc24(srcBmp); for (int y = 0; y < sh; y++) { if ((y + dstY < 0) | (y + dstY > dh - 1)) continue; for (int x = 0; x < sw; x++) { if ((x + dstX < 0) | (x + dstX > dw - 1)) continue; f = Math.Sin(y * pi / sh) * Math.Sin(x * pi / sw); dst.SetXY(x + dstX, y + dstY); src.SetXY(x, y); dst.R = (byte)((1f - f) * dst.R + f * src.R); dst.G = (byte)((1f - f) * dst.G + f * src.G); dst.B = (byte)((1f - f) * dst.B + f * src.B); } } CallDispose(src, 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 Radiance(ref Bitmap bmp, double factor, int cx, int cy) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; double r, r1, a; int f, rr, gg, bb, xx, yy, count; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { r = Math.Sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)); a = Math.Atan2(y - cy, x - cx); // radian f = (int)(factor * r * 0.1); if (f < 1) continue; rr = gg = bb = count = 0; for (int i = -f; i <= 0; i++) { r1 = r + i; xx = (int)(r1 * Math.Cos(a) + cx); yy = (int)(r1 * Math.Sin(a) + cy); if ((xx < 0) | (xx > w - 1)) continue; if ((yy < 0) | (yy > h - 1)) continue; src.SetXY(xx, yy); rr += src.R; gg += src.G; bb += src.B; count++; } dst.SetXY(x, y); dst.R = (byte)(rr / count); dst.G = (byte)(gg / count); dst.B = (byte)(bb / count); } CallDispose(dst, src, tmp); return true; }
public static bool KuwaharaOilPaint(ref Bitmap bmp, int block) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) 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 r, g, b, maxr, maxg, maxb, minr, ming, minb, indx, min; int[] rh = new int[16]; int[] gh = new int[16]; int[] bh = new int[16]; int rindx, gindx, bindx, countr, countg, countb; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(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; maxr = maxg = maxb = 0; minr = ming = minb = 255; for (int ix = xini[i]; ix <= xend[i]; ix++) for (int iy = yini[i]; iy <= yend[i]; iy++) { src.SetXY(ix, iy); if (src.R > maxr) maxr = src.R; if (src.R < minr) minr = src.R; if (src.G > maxg) maxg = src.G; if (src.G < ming) ming = src.G; if (src.B > maxb) maxb = src.B; if (src.B < minb) minb = src.B; } v[i] = (maxr - minr) + (maxg - ming) + (maxb - minb); } min = 1000; indx = 0; for (int i = 0; i <= 3; i++) if (v[i] < min) { min = v[i]; indx = i; } maxr = maxg = maxb = -1; for (int i = 0; i <= 15; i++) { rh[i] = gh[i] = bh[i] = 0; } for (int ix = xini[indx]; ix <= xend[indx]; ix++) for (int iy = yini[indx]; iy <= yend[indx]; iy++) { src.SetXY(ix, iy); rh[src.R >> 4]++; gh[src.G >> 4]++; bh[src.B >> 4]++; } rindx = gindx = bindx = 0; for (int i = 0; i <= 15; i++) { if (maxr < rh[i]) { maxr = rh[i]; rindx = i; } if (maxg < gh[i]) { maxg = gh[i]; gindx = i; } if (maxb < bh[i]) { maxb = bh[i]; bindx = i; } } r = g = b = countr = countg = countb = 0; for (int ix = xini[indx]; ix <= xend[indx]; ix++) for (int iy = yini[indx]; iy <= yend[indx]; iy++) { src.SetXY(ix, iy); if ((src.R >> 4) == rindx) { r += src.R; countr++; } if ((src.G >> 4) == gindx) { g += src.G; countg++; } if ((src.B >> 4) == bindx) { b += src.B; countb++; } } dst.SetXY(x, y); dst.R = (byte)(r / countr); dst.G = (byte)(g / countg); dst.B = (byte)(b / countb); } CallDispose(dst, src, tmp); return true; }
public static bool Rank(ref Bitmap bmp, int area, RankOp ro) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((area < 1) | (area > 10)) return false; int w = bmp.Width; int h = bmp.Height; int num = (2 * area + 1) * (2 * area + 1); byte rmax, gmax, bmax, rmin, gmin, bmin; Bitmap tmp = (Bitmap)bmp.Clone(); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { rmax = gmax = bmax = 0; rmin = gmin = bmin = 255; for (int iy = y - area; iy <= y + area; iy++) for (int ix = x - area; ix <= x + area; ix++) { if ((ix < 0) | (ix > w - 1)) continue; if ((iy < 0) | (iy > h - 1)) continue; src.SetXY(ix, iy); switch (ro) { case RankOp.Max: rmax = Math.Max(rmax, src.R); gmax = Math.Max(gmax, src.G); bmax = Math.Max(bmax, src.B); break; case RankOp.Mid: rmax = Math.Max(rmax, src.R); gmax = Math.Max(gmax, src.G); bmax = Math.Max(bmax, src.B); rmin = Math.Min(rmin, src.R); gmin = Math.Min(gmin, src.G); bmin = Math.Min(bmin, src.B); break; case RankOp.Min: rmin = Math.Min(rmin, src.R); gmin = Math.Min(gmin, src.G); bmin = Math.Min(bmin, src.B); break; } } dst.SetXY(x, y); switch (ro) { case RankOp.Max: dst.R = rmax; dst.G = gmax; dst.B = bmax; break; case RankOp.Mid: dst.R = ImageUtils.AdjustByte((rmax + rmin) / 2); dst.G = ImageUtils.AdjustByte((gmax + gmin) / 2); dst.B = ImageUtils.AdjustByte((bmax + bmin) / 2); break; case RankOp.Min: dst.R = rmin; dst.G = gmin; dst.B = bmin; break; } } CallDispose(dst, src, tmp); return true; }
public static bool Median(ref Bitmap bmp, int area) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((area < 1) | (area > 5)) return false; int w = bmp.Width; int h = bmp.Height; int num = (2 * area + 1) * (2 * area + 1); int mid = num / 2; // mid-index of zero starting array byte[] rr = new byte[num]; byte[] gg = new byte[num]; byte[] bb = new byte[num]; int indx; Bitmap tmp = (Bitmap)bmp.Clone(); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { indx = 0; for (int iy = y - area; iy <= y + area; iy++) for (int ix = x - area; ix <= x + area; ix++) { if ((ix < 0) | (ix > w - 1)) continue; if ((iy < 0) | (iy > h - 1)) continue; src.SetXY(ix, iy); rr[indx] = src.R; gg[indx] = src.G; bb[indx] = src.B; indx++; } Array.Sort(rr, 0, indx); Array.Sort(gg, 0, indx); Array.Sort(bb, 0, indx); if (indx == num) indx = mid; else indx = indx / 2; dst.SetXY(x, y); dst.R = rr[indx]; dst.G = gg[indx]; dst.B = bb[indx]; } CallDispose(dst, src, tmp); return true; }
public static bool Scramble(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 num = zone * zone; byte[] rr = new byte[num]; byte[] gg = new byte[num]; byte[] bb = new byte[num]; int[] ra = new int[num]; int indx; Random rnd = new Random(); int j, t; BmpProc24 src = new BmpProc24(bmp); for (int y = 0; y < h - 1; y += zone) for (int x = 0; x < w - 1; x += zone) { indx = 0; for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((ix > w - 1) | (iy > h - 1)) continue; src.SetXY(ix, iy); rr[indx] = src.R; gg[indx] = src.G; bb[indx] = src.B; indx++; } for (int i = 0; i < indx; i++) ra[i] = i; for (int i = 0; i < indx - 1; i++) { j = rnd.Next(i, indx); t = ra[i]; ra[i] = ra[j]; ra[j] = t; } indx = 0; for (int iy = y; iy < y + zone; iy++) for (int ix = x; ix < x + zone; ix++) { if ((ix > w - 1) | (iy > h - 1)) continue; src.SetXY(ix, iy); src.R = rr[ra[indx]]; src.G = gg[ra[indx]]; src.B = bb[ra[indx]]; indx++; } } src.Dispose(); return true; }
public static bool MotionBlur(ref Bitmap bmp, int range, double angle) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if (range < 2) return false; int w = bmp.Width; int h = bmp.Height; angle += 180; double sn = Math.Sin(angle * Math.PI / 180d); double cs = Math.Cos(angle * Math.PI / 180d); int[] dx = new int[range]; int[] dy = new int[range]; for (int i = 0; i < range; i++) { dx[i] = (int)(cs * (i + 1) + 0.5d); dy[i] = (int)(sn * (i + 1) + 0.5d); } int xx, yy, rr, gg, bb, count; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); rr = src.R; gg = src.G; bb = src.B; count = 1; for (int i = 1; i <= range; i++) { xx = x + dx[i - 1]; yy = y + dy[i - 1]; if ((xx < 0) | (xx > w - 1) | (yy < 0) | (yy > h - 1)) continue; src.SetXY(xx, yy); rr += src.R; gg += src.G; bb += src.B; count++; } dst.SetXY(x, y); dst.R = (byte)(rr / count); dst.G = (byte)(gg / count); dst.B = (byte)(bb / count); } CallDispose(dst, src, tmp); return true; }
public static bool Sobel(ref Bitmap bmp, bool fGrayScale) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int[,] hmask = { {-1, -2, -1}, { 0, 0, 0}, { 1, 2, 1}}; int[,] vmask = { {-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; int xx, yy, mx, my; double rv, gv, bv, rh, gh, bh; Bitmap tmp = (Bitmap)bmp.Clone(); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { rv = gv = bv = rh = gh = bh = 0; for (int iy = y - 1; iy <= y + 1; iy++) for (int ix = x - 1; ix <= x + 1; ix++) { mx = ix - x + 1; my = iy - y + 1; xx = ix; yy = iy; if ((ix < 0) | (ix > w - 1)) xx = x; if ((iy < 0) | (iy > h - 1)) yy = y; src.SetXY(xx, yy); rv += src.R * vmask[mx, my]; gv += src.G * vmask[mx, my]; bv += src.B * vmask[mx, my]; rh += src.R * hmask[mx, my]; gh += src.G * hmask[mx, my]; bh += src.B * hmask[mx, my]; } dst.SetXY(x, y); dst.R = AdjustByte(Math.Sqrt(rv * rv + rh * rh)); dst.G = AdjustByte(Math.Sqrt(gv * gv + gh * gh)); dst.B = AdjustByte(Math.Sqrt(bv * bv + bh * bh)); } CallDispose(dst, src, tmp); if (fGrayScale) return GrayScale(ref bmp); else return true; }
public static bool OilPaint(ref Bitmap bmp, int zone) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int[] rh = new int[16]; int[] gh = new int[16]; int[] bh = new int[16]; int rmax, gmax, bmax, rindx, gindx, bindx; int r, g, b, countr, countg, countb; Bitmap tmp = (Bitmap)bmp.Clone(); BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { rmax = gmax = bmax = -1; rindx = gindx = bindx = 0; for (int i = 0; i <= 15; i++) { rh[i] = gh[i] = bh[i] = 0; } for (int iy = y - zone; iy <= y + zone; iy++) for (int ix = x - zone; ix <= x + zone; ix++) { if ((iy < 0) | (iy > h - 1)) continue; if ((ix < 0) | (ix > w - 1)) continue; src.SetXY(ix, iy); rh[src.R >> 4]++; gh[src.G >> 4]++; bh[src.B >> 4]++; } for (int i = 0; i <= 15; i++) { if (rmax < rh[i]) { rmax = rh[i]; rindx = i; } if (gmax < gh[i]) { gmax = gh[i]; gindx = i; } if (bmax < bh[i]) { bmax = bh[i]; bindx = i; } } r = g = b = countr = countg = countb = 0; for (int iy = y - zone; iy <= y + zone; iy++) for (int ix = x - zone; ix <= x + zone; ix++) { if ((iy < 0) | (iy > h - 1)) continue; if ((ix < 0) | (ix > w - 1)) continue; src.SetXY(ix, iy); if ((src.R >> 4) == rindx) { r += src.R; countr++; } if ((src.G >> 4) == gindx) { g += src.G; countg++; } if ((src.B >> 4) == bindx) { b += src.B; countb++; } } dst.SetXY(x, y); dst.R = (byte)(r / countr); dst.G = (byte)(g / countg); dst.B = (byte)(b / countb); } CallDispose(dst, src, tmp); return true; }
public static bool BathroomWindow1(ref Bitmap bmp, int zone, BathroomWindowMode wm) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 2) | (zone > 100)) return false; int w = bmp.Width; int h = bmp.Height; int rnd = zone * 2 + 1; int xx, yy; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { xx = x; yy = y; switch (wm) { case BathroomWindowMode.bwVertical: xx = x + (x % rnd) - zone; break; case BathroomWindowMode.bwHorizontal: yy = y + (y % rnd) - zone; break; case BathroomWindowMode.bwBoth: xx = x + (x % rnd) - zone; yy = y + (y % rnd) - zone; break; } if ((xx > 0) & (xx < w) & (yy > 0) & (yy < h)) { dst.SetXY(x, y); src.SetXY(xx, yy); dst.R = src.R; dst.G = src.G; dst.B = src.B; } } CallDispose(dst, src, tmp); return true; }
public static bool BathroomWindow2(ref Bitmap bmp, int zone, int cx, int cy) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 2) | (zone > 100)) return false; int w = bmp.Width; int h = bmp.Height; int rnd = zone; if ((cx == 0) & (cy == 0)) { cx = w / 2; cy = h / 2; } int xx, yy; double a, r; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { r = Math.Sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)); a = Math.Atan2(y - cy, x - cx); // radian xx = x + ((int)(((a + Math.PI) * 180 / Math.PI + 0.2d * r)) % rnd) + zone; yy = y; if ((xx > 0) & (xx < w) & (yy > 0) & (yy < h)) { dst.SetXY(x, y); src.SetXY(xx, yy); dst.R = src.R; dst.G = src.G; dst.B = src.B; } } CallDispose(dst, src, tmp); return true; }