public static bool Luca(ref Bitmap bmp, bool bInvert, int outerRadius, int innerRadius, Color bkColor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((outerRadius - innerRadius) < 30) return false; int w = bmp.Width; int h = bmp.Height; int radius = outerRadius - innerRadius; int mg = 3; // margin for interpolations Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(tmp); g.Clear(bkColor); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); int rr = (radius + innerRadius) * 2 + 2; Bitmap dbmp = new Bitmap(rr, rr, PixelFormat.Format24bppRgb); double cx = (double)(radius + innerRadius + 1); double cy = (double)(radius + innerRadius + 1); g = Graphics.FromImage(dbmp); g.Clear(bkColor); g.Dispose(); RectangleF rct = new RectangleF(-1, -1, w + 1, h + 1); double r, a, xx, yy; double pi2 = Math.PI * 2d; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(dbmp); for (int y = 0; y < rr; y++) for (int x = 0; x < rr; x++) { r = Math.Sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)); a = Math.Atan2(y - cy, x - cx); // radian r = r - innerRadius; xx = (a + Math.PI) / pi2 * (w - 1); if (bInvert) yy = (1d - r / radius) * (h - 1); else yy = r / radius * (h - 1); if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; intBicubic(dst, src, x, y, xx, yy); } } CallDispose(dst, src, tmp, bmp); bmp = dbmp; if (bInvert) bmp.RotateFlip(RotateFlipType.Rotate270FlipNone); else bmp.RotateFlip(RotateFlipType.Rotate90FlipX); 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 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 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 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 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 BathroomWindow4(ref Bitmap bmp, int zone, double cx, double cy) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((zone < 2) | (zone > 100)) return false; int w = bmp.Width; int h = bmp.Height; if ((cx == 0d) & (cy == 0d)) { cx = w / 2; cy = h / 2; } int mg = 1; // margin for interpolations int rnd = zone; double a, r, xx, yy; Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, bmp.PixelFormat); Graphics g = Graphics.FromImage(tmp); g.Clear(Color.Gray); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); 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 r = r + ((int)r % rnd) - zone; xx = r * Math.Cos(a) + cx; yy = r * Math.Sin(a) + cy; if ((xx > 0) & (xx < w - 1) & (yy > 0) & (yy < h - 1)) { xx = xx + mg; yy = yy + mg; ImageUtility.intBilinear(dst, src, x, y, xx, yy); } } 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 CircleCrop(ref Bitmap bmp, double cx, double cy, double radius) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; if ((cx == 0) & (cy == 0)) { cx = (double)w / 2; cy = (double)h / 2; } Bitmap tmp = bmp.Clone() as Bitmap; RectangleF rct = new RectangleF(0, 0, w - 1, h - 1); double r, a, xx, yy; 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)); if (r < radius) continue; r = radius; a = Math.Atan2(y - cy, x - cx); // radian xx = r * Math.Cos(a) + cx; yy = r * Math.Sin(a) + cy; if (rct.Contains(new PointF((float)xx, (float)yy))) ImageUtility.intBilinear(dst, src, x, y, xx, yy); } CallDispose(dst, src, tmp); 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 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 Mirror(ref Bitmap bmp, double cx, double cy, double angle, Color bkColor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((angle < 0) | (angle > 360)) return false; int w = bmp.Width; int h = bmp.Height; if ((cx < 0) | (cx > w - 1) | (cy < 0) | (cy > h - 1)) return false; int mg = 3; // margin for interpolations RectangleF rct = new RectangleF(-1, -1, w + 1, h + 1); double deg = Math.PI / 180d; double a, b, sn, cs; if (Math.Abs(Math.Cos(angle * deg)) < 1.0E-20) a = 1.0E20; else a = Math.Sin(angle * deg) / Math.Cos(angle * deg); bool fUp = ((90 < angle) & (angle <= 270)); b = cy - a * cx; if (fUp) { sn = Math.Sin((angle - 90) * deg); cs = Math.Cos((angle - 90) * deg); } else { sn = Math.Sin((angle + 90) * deg); cs = Math.Cos((angle + 90) * deg); } Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, bmp.PixelFormat); Graphics g = Graphics.FromImage(tmp); g.Clear(bkColor); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); double xx, yy, dd; BmpProc24 src = new BmpProc24(tmp); BmpProc24 dst = new BmpProc24(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { if ((fUp & (a * x + b > y)) | (!fUp & (a * x + b < y))) { dd = Math.Abs(y - a * x - b) / Math.Sqrt(1 + a * a); if (y < a * x + b) { xx = x + 2 * dd * cs; yy = y + 2 * dd * sn; } else { xx = x - 2 * dd * cs; yy = y - 2 * dd * sn; } if (rct.Contains((float)xx, (float)yy)) { xx = xx + mg; yy = yy + mg; ImageUtility.intBicubic(dst, src, x, y, xx, yy); } else { dst[x, y, eRGB.r] = bkColor.R; dst[x, y, eRGB.g] = bkColor.G; dst[x, y, eRGB.b] = bkColor.B; } } } ImageUtility.CallDispose(dst, src, tmp); return true; }
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 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 Twist(ref Bitmap bmp, double factor, int frequency, double radius, int cx, int cy) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if (radius < 0) return false; if ((frequency < 1) | (frequency > 16)) return false; int w = bmp.Width; int h = bmp.Height; int q = frequency; int mg = 2; // margin for interpolations double c = factor; if ((cx == 0) & (cy == 0)) { cx = w / 2; cy = h / 2; } Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, bmp.PixelFormat); Graphics g = Graphics.FromImage(tmp); g.Clear(Color.LightGray); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); RectangleF rct = new RectangleF(0, 0, w - 1, h - 1); double r, a, xx, yy; 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)); if ((r > radius) | (r < 1)) continue; a = Math.Atan2(y - cy, x - cx); // radian a = a + c * Math.Sin(2d * q * r / radius * Math.PI) / r; xx = r * Math.Cos(a) + cx; yy = r * Math.Sin(a) + cy; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; intBicubic(dst, src, x, y, xx, yy); } else { if (xx < 0) xx = 0; if (xx > w - 1) xx = w - 1; if (yy < 0) yy = 0; if (yy > h - 1) yy = h - 1; xx = xx + mg; yy = yy + mg; intBicubic(dst, src, x, y, xx, yy); } } CallDispose(dst, src, tmp); 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 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 Wave(ref Bitmap bmp, WaveMode wm, double factor, double frequency) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int mg = 1; // margin for interpolations double f = factor; double c = frequency; double deg = Math.PI / 180d; RectangleF rct = new RectangleF(0, 0, w - 1, h - 1); Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, bmp.PixelFormat); Graphics g = Graphics.FromImage(tmp); g.Clear(Color.Gray); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); double xx, yy; 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 WaveMode.wmHorizontal: yy = y + f * Math.Sin(c * deg * x); break; case WaveMode.wmVertical: xx = x + f * Math.Sin(c * deg * y); break; case WaveMode.wmBoth: xx = x + f * Math.Sin(c * deg * y); yy = y + f * Math.Sin(c * deg * x); break; } if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; intBilinear(dst, src, x, y, xx, yy); } else { if (xx < 0) xx = 0; if (xx > w - 1) xx = w - 1; if (yy < 0) yy = 0; if (yy > h - 1) yy = h - 1; xx = xx + mg; yy = yy + mg; intBilinear(dst, src, x, y, xx, yy); } } 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; }
public static bool Blot(ref Bitmap bmp, double factor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int mg = 2; // margin for interpolations Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, bmp.PixelFormat); Graphics g = Graphics.FromImage(tmp); g.Clear(Color.Gray); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); RectangleF rct = new RectangleF(0, 0, w - 1, h - 1); double xx, yy; Random rnd = new Random(); 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 = (double)x + factor * ((rnd.Next(201) - 100) * 0.01d); yy = (double)y + factor * ((rnd.Next(201) - 100) * 0.01d); if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; intBilinear(dst, src, x, y, xx, yy); } } 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 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 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 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 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; ImageUtility.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 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 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 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 = ImageUtility.AdjustByte((rmax + rmin) / 2); dst.G = ImageUtility.AdjustByte((gmax + gmin) / 2); dst.B = ImageUtility.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 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 bool InsideOut(ref Bitmap bmp, double cx, double cy, double radius, Color bkColor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int mg = 2; // margin for interpolations if ((cx == 0) & (cy == 0)) { cx = (double)w / 2; cy = (double)h / 2; } Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, bmp.PixelFormat); Graphics g = Graphics.FromImage(tmp); g.Clear(bkColor); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); g = Graphics.FromImage(bmp); if (bkColor != Color.Transparent) g.Clear(bkColor); g.Dispose(); RectangleF rct = new RectangleF(-1, -1, w + 1, h + 1); double r, a, xx, yy; 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)); if (r > radius) continue; r = radius - r; a = Math.Atan2(y - cy, x - cx); // radian xx = r * Math.Cos(a) + cx; yy = r * Math.Sin(a) + cy; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; intBicubic(dst, src, x, y, xx, yy); } } CallDispose(dst, src, tmp); return true; }