public static bool transform(ref Bitmap bmp, TrapezoidSmallSide ss, double percent, Color bkColor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) { Console.WriteLine("* PIXEL FORMAT ERROR" + bmp.PixelFormat); return false; } if ((percent > 100d) | (percent < 1d)) { Console.WriteLine("* PERCENT ERROR" + percent); return false; } int w = bmp.Width; int h = bmp.Height; int mg = 3; // margin for interpolations RectangleF rct = new RectangleF(-1, -1, w + 1, h + 1); Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(tmp); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); Bitmap tmp2 = new Bitmap(w, h, PixelFormat.Format32bppArgb); percent = percent / 100d; double cw = (double)w / 2d; double ch = (double)h / 2d; double p = 1d; double xx, yy; BmpProc32 src = new BmpProc32(tmp); BmpProc32 dst = new BmpProc32(tmp2); switch (ss) { case TrapezoidSmallSide.ssUpper: for (int y = 0; y < h; y++) { p = (1d - percent) * (double)y / (double)(h - 1) + percent; for (int x = 0; x < w; x++) { xx = cw + ((double)x - cw) / p; yy = y; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; ImageUtils.intBicubic32(dst, src, x, y, xx, yy); } } } break; case TrapezoidSmallSide.ssLower: for (int y = 0; y < h; y++) { p = (percent - 1d) * (double)y / (double)(h - 1) + 1d; for (int x = 0; x < w; x++) { xx = cw + ((double)x - cw) / p; yy = y; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; ImageUtils.intBicubic32(dst, src, x, y, xx, yy); } } } break; case TrapezoidSmallSide.ssLeft: for (int x = 0; x < w; x++) { p = (1d - percent) * (double)x / (double)(w - 1) + percent; for (int y = 0; y < h; y++) { xx = x; yy = ch + ((double)y - ch) / p; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; ImageUtils.intBicubic32(dst, src, x, y, xx, yy); } } } break; case TrapezoidSmallSide.ssRight: for (int x = 0; x < w; x++) { p = (percent - 1d) * (double)x / (double)(w - 1) + 1d; for (int y = 0; y < h; y++) { xx = x; yy = ch + ((double)y - ch) / p; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; ImageUtils.intBicubic32(dst, src, x, y, xx, yy); } } } break; } ImageUtils.CallDispose(dst, src, tmp); if (bkColor == Color.Transparent) { bmp.Dispose(); bmp = tmp2; } else { g = Graphics.FromImage(bmp); g.Clear(bkColor); g.DrawImageUnscaled(tmp2, 0, 0); g.Dispose(); tmp2.Dispose(); } return true; }
public static bool AlphaSpots(ref Bitmap bmp, byte offset, params RadiusPos[] rp) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if (rp.Length == 0) 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(); double cx, cy, rr, r, f; BmpProc32 src = new BmpProc32(tmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) src[x, y, eRGB.a] = offset; for (int i = 0; i < rp.Length; i++) { cx = rp[i].PosX; cy = rp[i].PosY; rr = rp[i].Radius; rr = rr * rr; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { r = (x - cx) * (x - cx) + (y - cy) * (y - cy); f = 1.2d * (1d - r / rr); if (f > 1d) f = 1d; if (f > 0) src[x, y, eRGB.a] = Math.Max(src[x, y, eRGB.a], AdjustByte(255 * f)); } } src.Dispose(); bmp.Dispose(); bmp = tmp; return true; }
// 上の辺だけでとりあえず OK public static bool transform(ref Bitmap bmp, double percent, int centerX, Color bkColor) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if ((percent > 100d) | (percent < 1d)) return false; int w = bmp.Width; int h = bmp.Height; int mg = 3; // margin for interpolations (= 補完) RectangleF rct = new RectangleF(-1, -1, w + 1, h + 1); // -1 指定できるのか・・・ if (Math.Abs((double)w * percent / 100d / 2d) < Math.Abs(centerX)) { double d = Math.Abs( (double)centerX - (double)w * percent / 100d / 2d); if (centerX > 0) // x 軸正方向へのずれ { rct = new RectangleF(-1, -1, w + (float)d + 1, h + 1); } else { rct = new RectangleF(-1 -(float)d, -1, w + 1, h + 1); } } Bitmap tmp = new Bitmap(w + mg * 2, h + mg * 2, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(tmp); g.DrawImageUnscaled(bmp, mg, mg); g.Dispose(); Bitmap tmp2 = new Bitmap( (int)rct.Width, h, PixelFormat.Format32bppArgb); percent = percent / 100d; double cw = (double)w / 2d; double ch = (double)h / 2d; double p = 1d; double xx, yy; BmpProc32 src = new BmpProc32(tmp); BmpProc32 dst = new BmpProc32(tmp2); for (int y = 0; y < h; y++) { p = (1d - percent) * (double)y / (double)(h - 1) + percent; for (int x = 0; x < w; x++) { xx = cw + ((double)x - cw - centerX * ((double)(h - y) / (double)h)) / p; yy = y; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; ImageUtils.intBicubic32(dst, src, x, y, xx, yy); } } } Console.WriteLine("src size: {0},{1} / dest size {2},{3}", tmp.Width, tmp.Height, tmp2.Width, tmp2.Height); ImageUtils.CallDispose(dst, src, tmp); if (bkColor == Color.Transparent) { bmp.Dispose(); bmp = tmp2; } else { g = Graphics.FromImage(bmp); g.Clear(bkColor); g.DrawImageUnscaled(tmp2, 0, 0); g.Dispose(); tmp2.Dispose(); } return true; }
public static bool AlphaRects(ref Bitmap bmp, byte offset, params Rectangle[] rct) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; if (rct.Length == 0) 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(); double pi = Math.PI; double f; BmpProc32 src = new BmpProc32(tmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) src[x, y, eRGB.a] = offset; for (int i = 0; i < rct.Length; i++) { for (int y = rct[i].Y; y < rct[i].Y + rct[i].Height; y++) for (int x = rct[i].X; x < rct[i].X + rct[i].Width; x++) { if ((x < 0) | (x > w - 1) | (y < 0) | (y > h - 1)) continue; f = 1.2 * Math.Sin((x - rct[i].X) * pi / rct[i].Width) * Math.Sin((y - rct[i].Y) * pi / rct[i].Height); if (f > 1d) f = 1d; src[x, y, eRGB.a] = Math.Max(src[x, y, eRGB.a], (byte)(f * 255)); } } src.Dispose(); bmp.Dispose(); bmp = tmp; 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(); ImageUtils.GrayScale(ref bmp); if (stretch) ImageUtils.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 SetFramedAlpha(ref Bitmap bmp) { 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(); double pi = Math.PI; double f; BmpProc32 dst = new BmpProc32(tmp); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { f = Math.Sin(y * pi / h) * Math.Sin(x * pi / w); dst[x, y, eRGB.a] = (byte)(255 * f); } } dst.Dispose(); bmp.Dispose(); bmp = tmp; return true; }
public static bool AlphaGradient(ref Bitmap bmp, float[] factor, float[] position, GradientSide gs) { 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(); Color startColor = Color.White; Color endColor = Color.Black; Point start = new Point(-1, 0); Point end = new Point(0, 0); switch (gs) { case GradientSide.Left: end.X = w; break; case GradientSide.Right: start.X = w; break; case GradientSide.Upper: end.Y = h; break; case GradientSide.Lower: start.Y = h; break; case GradientSide.UpperLeft: end.X = w; end.Y = h; break; case GradientSide.UpperRight: start.X = w; end.Y = h; break; case GradientSide.LowerLeft: start.Y = h; end.X = w; break; case GradientSide.LowerRight: start.X = w; start.Y = h; break; } Blend bl = new Blend(); bl.Factors = factor; bl.Positions = position; LinearGradientBrush br = new LinearGradientBrush( start, end, startColor, endColor); br.Blend = bl; //br.GammaCorrection = true; Rectangle rct = new Rectangle(0, 0, w, h); g = Graphics.FromImage(bmp); g.FillRectangle(br, rct); g.Dispose(); BmpProc24 src = new BmpProc24(bmp); BmpProc32 dst = new BmpProc32(tmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) dst[x, y, eRGB.a] = src[x, y, eRGB.r]; CallDispose(dst, src, bmp); bmp = tmp; return true; }
public static bool MotionBlur32(ref Bitmap bmp, int range, double angle) { if (bmp.PixelFormat != PixelFormat.Format32bppArgb) 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, aa, rr, gg, bb, count; Bitmap tmp = bmp.Clone() as Bitmap; BmpProc32 src = new BmpProc32(tmp); BmpProc32 dst = new BmpProc32(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { src.SetXY(x, y); aa = src.A; rr = src.R * src.A; gg = src.G * src.A; bb = src.B * src.A; 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); aa += src.A; rr += src.R * src.A; gg += src.G * src.A; bb += src.B * src.A; count++; } dst.SetXY(x, y); dst.A = (byte)(aa / count); dst.R = AdjustByte((double)rr / aa); dst.G = AdjustByte((double)gg / aa); dst.B = AdjustByte((double)bb / aa); } CallDispose(dst, src, tmp); return true; }
public static bool SetAlpha(ref Bitmap bmp, int percent) { 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(); byte alpha = (byte)(255 * percent / 100); BmpProc32 dst = new BmpProc32(tmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) dst[x, y, eRGB.a] = alpha; dst.Dispose(); bmp.Dispose(); bmp = tmp; return true; }
public static void intBilinear32(BmpProc32 dst, BmpProc32 src, int dstX, int dstY, double srcX, double srcY) { int x1 = (int)Math.Floor(srcX); int x2 = x1 + 1; double fx2 = srcX - x1; double fx1 = 1 - fx2; int y1 = (int)Math.Floor(srcY); int y2 = y1 + 1; double fy2 = srcY - y1; double fy1 = 1 - fy2; byte aa = (byte)(src[x1, y1, eRGB.a] * fx1 * fy1 + src[x2, y1, eRGB.a] * fx2 * fy1 + src[x1, y2, eRGB.a] * fx1 * fy2 + src[x2, y2, eRGB.a] * fx2 * fy2); dst[dstX, dstY, eRGB.a] = aa; if (aa != 0) { dst[dstX, dstY, eRGB.r] = (byte)((src[x1, y1, eRGB.r] * src[x1, y1, eRGB.a] * fx1 * fy1 + src[x2, y1, eRGB.r] * src[x2, y1, eRGB.a] * fx2 * fy1 + src[x1, y2, eRGB.r] * src[x1, y2, eRGB.a] * fx1 * fy2 + src[x2, y2, eRGB.r] * src[x2, y2, eRGB.a] * fx2 * fy2) / aa); dst[dstX, dstY, eRGB.g] = (byte)((src[x1, y1, eRGB.g] * src[x1, y1, eRGB.a] * fx1 * fy1 + src[x2, y1, eRGB.g] * src[x2, y1, eRGB.a] * fx2 * fy1 + src[x1, y2, eRGB.g] * src[x1, y2, eRGB.a] * fx1 * fy2 + src[x2, y2, eRGB.g] * src[x2, y2, eRGB.a] * fx2 * fy2) / aa); dst[dstX, dstY, eRGB.b] = (byte)((src[x1, y1, eRGB.b] * src[x1, y1, eRGB.a] * fx1 * fy1 + src[x2, y1, eRGB.b] * src[x2, y1, eRGB.a] * fx2 * fy1 + src[x1, y2, eRGB.b] * src[x1, y2, eRGB.a] * fx1 * fy2 + src[x2, y2, eRGB.b] * src[x2, y2, eRGB.a] * fx2 * fy2) / aa); } }
public static void intBicubic32(BmpProc32 dst, BmpProc32 src, int dstX, int dstY, double srcX, double srcY) { int xi = (int)Math.Floor(srcX); int yi = (int)Math.Floor(srcY); double rr, gg, bb, aa; double dx, dy, wx, wy; rr = gg = bb = aa = 0; for (int iy = yi - 1; iy < yi + 3; iy++) for (int ix = xi - 1; ix < xi + 3; ix++) { dx = Math.Abs(srcX - ix); dy = Math.Abs(srcY - iy); if (dx < 1) wx = (dx - 1d) * (dx * dx - dx - 1d); else wx = -(dx - 1d) * (dx - 2d) * (dx - 2d); if (dy < 1) wy = (dy - 1d) * (dy * dy - dy - 1d); else wy = -(dy - 1d) * (dy - 2d) * (dy - 2d); src.SetXY(ix, iy); aa += src.A * wx * wy; rr += src.R * src.A * wx * wy; gg += src.G * src.A * wx * wy; bb += src.B * src.A * wx * wy; } dst[dstX, dstY, eRGB.a] = ImageUtils.AdjustByte(aa); if (aa != 0) { dst.SetXY(dstX, dstY); dst.R = AdjustByte(rr / aa); dst.G = AdjustByte(gg / aa); dst.B = AdjustByte(bb / aa); } }
public static bool Ellipse2(ref Bitmap bmp) { if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; int mg = 3; // margin for interpolations int q = Math.Max(w, h); RectangleF rct = new RectangleF(-1, -1, q + 1, q + 1); Bitmap tmp1 = new Bitmap(q + mg * 2, q + mg * 2, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(tmp1); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(bmp, mg, mg, q, q); g.Dispose(); Bitmap tmp2 = new Bitmap(q, q, PixelFormat.Format32bppArgb); g = Graphics.FromImage(tmp2); g.Dispose(); double l, xx, yy; double r = (double)q / 2d; BmpProc32 src = new BmpProc32(tmp1); BmpProc32 dst = new BmpProc32(tmp2); for (int y = 1; y < q; y++) for (int x = 0; x < q; x++) { l = Math.Sqrt(2d * r * y - y * y); if (l == 0) xx = 0; else xx = r * (x - r) / l + r; yy = y; if (rct.Contains(new PointF((float)xx, (float)yy))) { xx = xx + mg; yy = yy + mg; intBicubic32(dst, src, x, y, xx, yy); } } CallDispose(dst, src, tmp1); Bitmap tmp3 = new Bitmap(w, h, PixelFormat.Format32bppArgb); g = Graphics.FromImage(tmp3); g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(tmp2, 0, 0, w, h); g.Dispose(); tmp2.Dispose(); bmp.Dispose(); bmp = tmp3; 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 Blur32(ref Bitmap bmp, int zone) { if (bmp.PixelFormat != PixelFormat.Format32bppArgb) return false; if ((zone < 1) | (zone > 10)) return false; int w = bmp.Width; int h = bmp.Height; int suma, sumr, sumg, sumb, count; Bitmap tmp = (Bitmap)bmp.Clone(); BmpProc32 src = new BmpProc32(tmp); BmpProc32 dst = new BmpProc32(bmp); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { suma = sumr = sumg = sumb = count = 0; for (int iy = y - zone; iy <= y + zone; iy++) for (int ix = x - zone; ix <= x + zone; ix++) { if ((ix < 0) | (ix > w - 1)) continue; if ((iy < 0) | (iy > h - 1)) continue; src.SetXY(ix, iy); suma += src.A; sumr += src.R * src.A; sumg += src.G * src.A; sumb += src.B * src.A; count++; } dst.SetXY(x, y); dst.A = (byte)(suma / count); dst.R = AdjustByte((double)sumr / suma); dst.G = AdjustByte((double)sumg / suma); dst.B = AdjustByte((double)sumb / suma); } CallDispose(dst, src, tmp); return true; }