【C# / GDI】简单图像处理方法
发表于2018-07-17
图像处理原理其实就是对图像像素点的遍历操作。下面就和大家分享下简单的图像处理方法。
图像是由像素组成,像素是由RGB(红绿蓝)的分量构成,所以改变颜色效果的方法,就是去改变三个分量的值。
灰度,亮度,分量之类的处理都是直接对单个像素点的R G B 值进行修改重新赋值
模糊,浮雕之类的效果则是取像素和周围的像素点进行必要的运算后重新赋值
具体算法和原理看代码基本都是可以看懂的、大家自己理解一下好了,其实还是挺简单的、程序界面没什么好说的,就是在调用模块中的不同方法而已。
- 补充1:使用System.Drawing命名空间下的方法对图像进行取像素和置像素的操作速度不理想、本类仅供图像基本处理的原理和方法参考,实际运用价值不大。
- 补充2:如果想实际运用,需要对类进行一定的修改,否则由于处理速度慢的关系会导致调用线程假死
如果想要提升处理速度,可以将图像作为字节集对象处理,而不是使用.Net的GDI方法。
源代码如下:
using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Drawing.Imaging; using ge = AyaSimpleImage.General; namespace AyaSimpleImage { /// <summary> /// 图像处理类 By:ls9512 20130831 /// </summary> public class BmpCtrl { #region 构造/初始化 /// <summary> /// 构造方法 /// </summary> public BmpCtrl() { } #endregion /// <summary> /// 以逆时针为方向对图像进行旋转 /// </summary> /// <param name="b">位图流</param> /// <param name="angle">旋转角度[0,360](前台给的)</param> /// /// <returns></returns> public Bitmap RotateImg(Bitmap b, int angle) { angle = angle % 360;//弧度转换 double radian = angle * Math.PI / 180.0; double cos = Math.Cos(radian); double sin = Math.Sin(radian);//原图的宽和高 int w = b.Width; int h = b.Height; int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin))); int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));//目标位图 Bitmap dsImage = new Bitmap(W, H); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//计算偏移量 Point Offset = new Point((W - w) / 2, (H - h) / 2);//构造图像显示区域:让图像的中心与窗口的中心点一致 Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h); Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); g.TranslateTransform(center.X, center.Y); g.RotateTransform(360 - angle);//恢复图像在水平和垂直方向的平移 g.TranslateTransform(-center.X, -center.Y); g.DrawImage(b, rect);//重至绘图的所有变换 g.ResetTransform(); g.Save(); g.Dispose(); //保存旋转后的图片 b.Dispose(); return dsImage; } #region 灰度/黑白 /// <summary> /// 图像灰度化 /// </summary> /// <param name="orBitmap">原始图像</param> /// <param name="Step">灰阶</param> /// <returns>返回图像</returns> public Bitmap BitMapToGrapBitMap(Bitmap orBitmap, int Step) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); //准备每一阶的灰度 int[] stepx = new int[Step]; for (int i = 0; i < Step; i++) { stepx[i] = (int)(255.0 / (Step - 1) * i); } for (int i = 0; i < orBitmap.Height; i++) { for (int j = 0; j < orBitmap.Width; j++) { //取像素点颜色 Color co = orBitmap.GetPixel(j, i); //计算明度 int cx = (int)((Convert.ToInt32(co.R) + Convert.ToInt32(co.G) + Convert.ToInt32(co.B)) * 1.0 / 3); //对应到阶 cx = (int)(cx * Step * 1.0 / 255); if (cx < 0) cx = 0; if (cx > Step - 1) cx = Step - 1; cx = stepx[cx]; co = Color.FromArgb(cx, cx, cx); //设置像素点颜色 reBitmap.SetPixel(j, i, co); } } return reBitmap; } /// <summary> /// 图像黑白化1(最值法) /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToBW1(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); for (int i = 0; i < orBitmap.Height; i++) { for (int j = 0; j < orBitmap.Width; j++) { int x = 0; //最大值法置黑白图像 Color c = orBitmap.GetPixel(j, i); if (c.R > c.B) x = c.R; else x = c.B; if (c.G > x) x = c.G; reBitmap.SetPixel(j, i, Color.FromArgb(x, x, x)); } } return reBitmap; } /// <summary> /// 图像黑白化2(加权平均值法) /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToBW2(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); for (int i = 0; i < orBitmap.Height; i++) { for (int j = 0; j < orBitmap.Width; j++) { int x = 0; //加权平均求黑白色 Color c = orBitmap.GetPixel(j, i); x = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11); reBitmap.SetPixel(j, i, Color.FromArgb(x, x, x)); } } return reBitmap; } /// <summary> /// 图像黑白2值化 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToBW2Value(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); //计算平均颜色 int average = 0; for (int i = 0; i < orBitmap.Width; i++) { for (int j = 0; j < orBitmap.Height; j++) { Color color = orBitmap.GetPixel(i, j); average += color.B; } } average = (int)average / (orBitmap.Width * orBitmap.Height); for (int i = 0; i < orBitmap.Height; i++) { for (int j = 0; j < orBitmap.Width; j++) { //设置像素点颜色 if (orBitmap.GetPixel(j, i).B < average) { reBitmap.SetPixel(j, i, Color.Black); } else { reBitmap.SetPixel(j, i, Color.White); } } } return reBitmap; } #endregion #region 色彩 /// <summary> /// 图像底片&反色 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToAntiColor(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); for (int i = 0; i < orBitmap.Height; i++) { for (int j = 0; j < orBitmap.Width; j++) { //反色 Color c = orBitmap.GetPixel(j, i); reBitmap.SetPixel(j, i, Color.FromArgb(255 - c.R, 255 - c.G, 255 - c.B)); } } return reBitmap; } #region 模糊/锐化 /// <summary> /// 图像高斯模糊 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToGaussianBlur(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); //高斯模板 int[] Gauss = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; Color pixel; for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { int r = 0, g = 0, b = 0; int Index = 0; for (int col = -1; col <= 1; col++) { for (int row = -1; row <= 1; row++) { pixel = orBitmap.GetPixel(j + row, i + col); r += pixel.R * Gauss[Index]; g += pixel.G * Gauss[Index]; b += pixel.B * Gauss[Index]; Index++; } } r /= 16; g /= 16; b /= 16; //处理颜色值溢出 r = r > 255 ? 255 : r; r = r < 0 ? 0 : r; g = g > 255 ? 255 : g; g = g < 0 ? 0 : g; b = b > 255 ? 255 : b; b = b < 0 ? 0 : b; reBitmap.SetPixel(j, i, Color.FromArgb(r, g, b)); } } return reBitmap; } /// <summary> /// 模糊效果 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToBlur(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Color pixel1, pixel2, pixel3, pixel4; int Strength = 1; for (int i = 0; i < orBitmap.Height; i++) { for (int j = 0; j < orBitmap.Width; j++) { int r = 0, g = 0, b = 0; int x = i, y = j; if (x == 0) x = 1; if (y == 0) y = 1; if (x == orBitmap.Height - 1) x = orBitmap.Height - 2; if (y == orBitmap.Width - 1) y = orBitmap.Width - 2; pixel1 = orBitmap.GetPixel(y - Strength, x - Strength); pixel2 = orBitmap.GetPixel(y + Strength, x + Strength); pixel3 = orBitmap.GetPixel(y - Strength, x + Strength); pixel4 = orBitmap.GetPixel(y + Strength, x - Strength); pixel2 = Color.FromArgb((pixel2.R + pixel1.R + pixel3.R + pixel4.R) / 4, (pixel2.G + pixel1.G + pixel3.G + pixel4.G) / 4, (pixel2.B + pixel1.B + pixel3.B + pixel4.B) / 4); r = pixel2.R; g = pixel2.G; b = pixel2.B; //防止溢出 if (r > 255) r = 255; if (r < 0) r = 0; if (g > 255) g = 255; if (g < 0) g = 0; if (b > 255) b = 255; if (b < 0) b = 0; reBitmap.SetPixel(j, i, Color.FromArgb(r, g, b)); } } return reBitmap; } /// <summary> /// 图像锐化 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToSharpen(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); //拉普拉斯模板 int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 }; Color pixel; for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { int r = 0, g = 0, b = 0; int Index = 0; for (int col = -1; col <= 1; col++) { for (int row = -1; row <= 1; row++) { pixel = orBitmap.GetPixel(j + row, i + col); r += pixel.R * Laplacian[Index]; g += pixel.G * Laplacian[Index]; b += pixel.B * Laplacian[Index]; Index++; } } //处理颜色值溢出 r = r > 255 ? 255 : r; r = r < 0 ? 0 : r; g = g > 255 ? 255 : g; g = g < 0 ? 0 : g; b = b > 255 ? 255 : b; b = b < 0 ? 0 : b; reBitmap.SetPixel(j - 1, i - 1, Color.FromArgb(r, g, b)); } } return reBitmap; } /// <summary> /// 图像雾化 /// </summary> /// <param name="orBitmap">原始图像</param> /// <param name="Strength">雾化强度(0-10)</param> /// <returns>返回图像</returns> public Bitmap BitMapToAtomization(Bitmap orBitmap, int Strength) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Color pixel; System.Random randx = new Random(); for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { //随机雾化强度(可自己调整) int k = randx.Next(Strength + 1, (Strength + 1) * 10); //像素块大小 int dx = j + k % 19; int dy = i + k % 19; if (dx >= orBitmap.Width) dx = orBitmap.Width - 1; if (dy >= orBitmap.Height) dy = orBitmap.Height - 1; pixel = orBitmap.GetPixel(dx, dy); int r = pixel.R, g = pixel.G, b = pixel.B; Color c1, c2, c3, c4; c1 = orBitmap.GetPixel(j - 1, i - 1); c2 = orBitmap.GetPixel(j - 1, i + 1); c3 = orBitmap.GetPixel(j + 1, i - 1); c4 = orBitmap.GetPixel(j + 1, i + 1); r = (r + c1.R + c2.R + c3.R + c4.R) / 5; g = (g + c1.G + c2.G + c3.G + c4.G) / 5; b = (b + c1.B + c2.B + c3.B + c4.B) / 5; reBitmap.SetPixel(j, i, Color.FromArgb(r, g, b)); } } return reBitmap; } #endregion #region 艺术/绘画 /// <summary> /// 图像浮雕效果 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToRelief(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Color pixel1, pixel2; for (int i = 0; i < orBitmap.Height - 1; i++) { for (int j = 0; j < orBitmap.Width - 1; j++) { int r = 0, g = 0, b = 0; pixel1 = orBitmap.GetPixel(j, i); pixel2 = orBitmap.GetPixel(j + 1, i + 1); r = Math.Abs(pixel1.R - pixel2.R + 128); g = Math.Abs(pixel1.G - pixel2.G + 128); b = Math.Abs(pixel1.B - pixel2.B + 128); if (r > 255) r = 255; if (r < 0) r = 0; if (g > 255) g = 255; if (g < 0) g = 0; if (b > 255) b = 255; if (b < 0) b = 0; reBitmap.SetPixel(j, i, Color.FromArgb(r, g, b)); } } return reBitmap; } /// <summary> /// 油画效果 /// </summary> /// <param name="orBitmap">原始图像</param> /// <param name="Strength">强度(0-10)</param> /// <returns>返回图像</returns> public Bitmap BitMapToPainting(Bitmap orBitmap, int Strength) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); //产生随机数序列 Random randx = new Random(); //强度 Strength++; Strength *= 2; int i = 0; while (i < orBitmap.Width) { int j = 0; while (j < orBitmap.Height) { Color color; int iPosx = randx.Next(100000) % Strength; int iPosy = randx.Next(100000) % Strength; if (i + iPosx >= orBitmap.Width) iPosx = -1 * randx.Next(0, orBitmap.Width - i); if (j + iPosy >= orBitmap.Height) iPosy = -1 * randx.Next(0, orBitmap.Height - j); //将该点的RGB值设置成附近iModel点之内的任一点 color = orBitmap.GetPixel(i + iPosx, j + iPosy); reBitmap.SetPixel(i, j, color); j++; } i++; } return reBitmap; } /// <summary> /// 积木效果 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToBlock(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { Color Color = orBitmap.GetPixel(j, i); int r, g, b; if (Color.R > 128) r = 255; else r = 0; if (Color.G > 128) g = 255; else g = 0; if (Color.B > 128) b = 255; else b = 0; Color nColor = Color.FromArgb(255, r, g, b); reBitmap.SetPixel(j, i, nColor); } } return reBitmap; } /// <summary> /// 彩色线稿效果 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToColorLineArt(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Color pixel1, pixel2; for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { int r = 0, g = 0, b = 0; pixel1 = orBitmap.GetPixel(j, i); pixel2 = orBitmap.GetPixel(j - 1, i - 1); //pixel3 = orBitmap.GetPixel(j + 1, i + 1); //pixel2 = Color.FromArgb((pixel2.R + pixel3.R) / 2, (pixel2.G + pixel3.G) / 2, (pixel2.B + pixel3.B) / 2); r = 255 - Math.Abs(pixel1.R - pixel2.R); g = 255 - Math.Abs(pixel1.G - pixel2.G); b = 255 - Math.Abs(pixel1.B - pixel2.B); //防止溢出 if (r > 255) r = 255; if (r < 0) r = 0; if (g > 255) g = 255; if (g < 0) g = 0; if (b > 255) b = 255; if (b < 0) b = 0; reBitmap.SetPixel(j, i, Color.FromArgb(r, g, b)); } } return reBitmap; } /// <summary> /// 炭笔效果 /// </summary> /// <param name="orBitmap">原始图像</param> /// <returns>返回图像</returns> public Bitmap BitMapToCharcoal(Bitmap orBitmap) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Color pixel1, pixel2, pixel3, c; //计算平均颜色 int average = 0; for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { int r = 0, g = 0, b = 0; pixel1 = orBitmap.GetPixel(j, i); pixel2 = orBitmap.GetPixel(j - 1, i - 1); pixel3 = orBitmap.GetPixel(j + 1, i + 1); //pixel2 = Color.FromArgb((pixel2.R + pixel3.R) / 2, (pixel2.G + pixel3.G) / 2, (pixel2.B + pixel3.B) / 2); r = 255 - Math.Abs(pixel1.R - pixel2.R); g = 255 - Math.Abs(pixel1.G - pixel2.G); b = 255 - Math.Abs(pixel1.B - pixel2.B); if (r > 255) r = 255; if (r < 0) r = 0; if (g > 255) g = 255; if (g < 0) g = 0; if (b > 255) b = 255; if (b < 0) b = 0; c = Color.FromArgb(r, g, b); reBitmap.SetPixel(j, i, c); average += c.B; } } average /= orBitmap.Width * orBitmap.Height; for (int i = 0; i < orBitmap.Width; i++) { for (int j = 0; j < orBitmap.Height; j++) { //设置像素点颜色 if (reBitmap.GetPixel(i, j).B < average) { reBitmap.SetPixel(i, j, Color.Black); } else { reBitmap.SetPixel(i, j, Color.White); } } } return reBitmap; } #endregion #region 光照 /// <summary> /// 图像中心光照 /// </summary> /// <param name="orBitmap">原始图像</param> /// <param name="Strength">光照强度(0-10)</param> /// <param name="Offest">光照中心</param> /// <returns>返回图像</returns> public Bitmap BitMapToIllumination(Bitmap orBitmap, int Strength, Point CenterPoint) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); int A = orBitmap.Width / 2; int B = orBitmap.Height / 2; //Center图片中心点,发亮此值会让强光中心发生偏移 Point Center = CenterPoint; //R强光照射面的半径,即”光晕” int length = 0; if (orBitmap.Width > orBitmap.Height) length = orBitmap.Width; else length = orBitmap.Height; int R = Math.Min(length, length); //计算强度 R = (int)(Strength * 1.0 / 10 * R); for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { float RLength = (float)Math.Sqrt(Math.Pow((j - Center.X), 2) + Math.Pow((i - Center.Y), 2)); //如果像素位于”光晕”之内 if (RLength < R) { Color Color = orBitmap.GetPixel(j, i); int r, g, b; //220亮度增加常量,该值越大,光亮度越强 float Pixel = 220.0f * (1.0f - RLength / R); r = Color.R + (int)Pixel; r = Math.Max(0, Math.Min(r, 255)); g = Color.G + (int)Pixel; g = Math.Max(0, Math.Min(g, 255)); b = Color.B + (int)Pixel; b = Math.Max(0, Math.Min(b, 255)); //将增亮后的像素值回写到位图 Color nColor = Color.FromArgb(255, r, g, b); reBitmap.SetPixel(j, i, nColor); } else { reBitmap.SetPixel(j, i, orBitmap.GetPixel(j, i)); } } } return reBitmap; } /// <summary> /// 补光 /// </summary> /// <param name="orBitmap">原始图像</param> /// <param name="Strength">强度(0-10)</param> /// <returns>返回图像</returns> public Bitmap BitMapToUpLight(Bitmap orBitmap, int Strength) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Strength++; Strength *= 10; for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { Color Color = orBitmap.GetPixel(j, i); int r, g, b; r = Color.R + Strength; if (r >= 255) r = 255; g = Color.G + Strength; if (g > 255) g = 255; b = Color.B + Strength; if (b > 255) b = 255; Color nColor = Color.FromArgb(255, r, g, b); reBitmap.SetPixel(j, i, nColor); } } return reBitmap; } /// <summary> /// 减光 /// </summary> /// <param name="orBitmap">原始图像</param> /// <param name="Strength">强度(0-10)</param> /// <returns>返回图像</returns> public Bitmap BitMapToDownLight(Bitmap orBitmap, int Strength) { //返回图像 Bitmap reBitmap = new Bitmap(orBitmap.Width, orBitmap.Height); Strength++; Strength *= 10; for (int i = 1; i < orBitmap.Height - 1; i++) { for (int j = 1; j < orBitmap.Width - 1; j++) { Color Color = orBitmap.GetPixel(j, i); int r, g, b; r = Color.R - Strength; if (r < 0) r = 0; g = Color.G - Strength; if (g < 0) g = 0; b = Color.B - Strength; if (b < 0) b = 0; Color nColor = Color.FromArgb(255, r, g, b); reBitmap.SetPixel(j, i, nColor); } } return reBitmap; } #endregion } }
来自:https://blog.csdn.net/ls9512/article/details/46804591
如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引