原文链接:https://blog.csdn.net/wchstrife/article/details/78984735
使用C#进行图像处理
前言
之前一直认为图像处理是一件很高大上的事情,在一门选修课的课上遇到一个图像处理的作业,上手几个简单的图像处理的算法,也算是入了个最简单的门。
界面简单而又丑陋,代码命名也比较随意,大家重点关注算法就好
在这里一共实现了暗角、降低亮度、灰度、浮雕、马赛克、扩散六个算法。
项目github地址:https://github.com/wchstrife/ImageProcessing
界面设计
这里使用的是VS2010,新建C#工程之后。在界面上画出
- 2个pictureBox作为显示的图片的控件。
- 6个button作为不同效果的触发器,
- 2个button作为文件打开和保存的触发器,
- 1个label负责展示运行时间。
文件打开与保存
这里主要就是调用了openFileDialog和openFileDialog,不具体说。
打开文件:
private void btnopen_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { string path = openFileDialog1.FileName; bitmap = (Bitmap)Image.FromFile(path); pbimage.Image = bitmap.Clone() as Image; } }
保存文件:
private void btnsave_Click(object sender, EventArgs e) { sw1.Reset(); if (saveFileDialog1.ShowDialog() == DialogResult.OK) { sw1.Start(); string filename = saveFileDialog1.FileName.ToString(); if (filename.Length > 0) { string fileextname = filename.Substring(filename.IndexOf('.') + 1).ToString(); ImageFormat imagefomart = null; if (fileextname.Length > 0) { switch (fileextname.ToLower()) { case "jpg": imagefomart = ImageFormat.Jpeg; break; case "jpeg": imagefomart = ImageFormat.Jpeg; break; case "bmp": imagefomart = ImageFormat.Bmp; break; case "gif": imagefomart = ImageFormat.Gif; break; default:; break; } } if(imagefomart==null) { imagefomart = ImageFormat.Jpeg; } try { this.pbnewimage.Image.Save(filename, imagefomart); sw1.Stop(); label1.Text = "时间:" + sw1.ElapsedMilliseconds; } catch (Exception ex) { throw ex; } } } }
添加暗角
暗角就是在图像的四角添加逐渐变黑的一个圈。
基本步骤:
计算顶点与中心的距离maxDistance
计算每个像素点与中心的距离distance
计算factor = distance / maxDistance
将当前像素点的颜色设置为 原颜色 * (1-factor)
效果图
实现算法:
private void btndark_Click(object sender, EventArgs e) { newbitmap = bitmap.Clone() as Bitmap; sw1.Reset(); sw1.Start(); int width = newbitmap.Width; int height = newbitmap.Height; float cx = width / 2; float cy = height / 2; float maxdist = cx * cx + cy * cy; float currdist = 0, factor; Color pixel; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { currdist = ((float)i - cx) * ((float)i - cx) + ((float)j - cy) + ((float)j - cy); factor = currdist / maxdist; pixel = newbitmap.GetPixel(i,j); int red = (int)(pixel.R * (1 - factor)); int green = (int)(pixel.G * (1 - factor)); int blue = (int)(pixel.R * (1 - factor)); newbitmap.SetPixel(i, j, Color.FromArgb(red, green, blue)); } } sw1.Stop(); label1.Text = sw1.ElapsedMilliseconds.ToString(); pbnewimage.Image = newbitmap.Clone() as Image; }
降低亮度
基本步骤
降低亮度就是设置当前像素的颜色为原来的一个小于1的系数,要注意各颜色的分量不能超过255。这里我们选取0.6作为系数。
效果图
实现代码
private void btnvright_Click(object sender, EventArgs e) { if (bitmap != null) { newbitmap = bitmap.Clone() as Bitmap; sw1.Reset(); sw1.Restart(); Color pixel; int red, green, blue; for (int x = 0; x < newbitmap.Width; x++) { for (int y = 0; y < newbitmap.Height; y++) { pixel = newbitmap.GetPixel(x, y); red = (int)(pixel.R * 0.6); green = (int)(pixel.G * 0.6); blue = (int)(pixel.B * 0.6); newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue)); } } sw1.Stop(); label1.Text = sw1.ElapsedMilliseconds.ToString(); pbnewimage.Image = newbitmap.Clone() as Image; } }
去色
基本步骤
去色也就是要把照片灰化,将照片的RGB调节为灰色的。
具体的就是要把当前像素点的颜色按下面的公式的调整
gary = 0.3 * R + 0.59 * G + 0.11 * B
效果图
实现算法
private void btndecolor_Click(object sender, EventArgs e) { if (bitmap != null) { newbitmap = bitmap.Clone() as Bitmap; sw1.Reset(); sw1.Restart(); Color pixel; int gray; for (int x = 0; x < newbitmap.Width; x++) { for (int y = 0; y < newbitmap.Height; y++) { pixel = newbitmap.GetPixel(x, y); gray = (int)(0.3 * pixel.R + 0.59 * pixel.G + 0.11 * pixel.B); newbitmap.SetPixel(x, y, Color.FromArgb(gray, gray, gray)); } } sw1.Stop(); label1.Text = sw1.ElapsedMilliseconds.ToString(); pbnewimage.Image = newbitmap.Clone() as Image; } }
浮雕
基本步骤
浮雕效果就是把RGB三个颜色取反。
具体的实现用255-当前颜色的分量
效果图
### 实现算法
private void btnrelief_Click(object sender, EventArgs e) { if (bitmap != null) { newbitmap = bitmap.Clone() as Bitmap; sw1.Reset(); sw1.Restart(); Color pixel; int red, green, blue; for (int x = 0; x < newbitmap.Width; x++) { for (int y = 0; y < newbitmap.Height; y++) { pixel = newbitmap.GetPixel(x, y); red = (int)(255 - pixel.R); green = (int)(255 - pixel.G); blue = (int)(255 - pixel.B); newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue)); } } sw1.Stop(); label1.Text = sw1.ElapsedMilliseconds.ToString(); pbnewimage.Image = newbitmap.Clone() as Image; } }
马赛克
基本步骤
马赛克的基本思想就是把一个像素点周围的点的像素取个平均,然后把这些像素点的颜色设为这个平均值。
周围的像素点取的越多,马克赛的效果也就越明显。
效果图
实现算法
private void btnmosaic_Click(object sender, EventArgs e) { if (bitmap != null) { newbitmap = bitmap.Clone() as Bitmap; sw1.Reset(); sw1.Restart(); int RIDIO = 50;//马赛克的尺度,默认为周围两个像素 for (int h = 0; h < newbitmap.Height; h += RIDIO) { for (int w = 0; w < newbitmap.Width; w += RIDIO) { int avgRed = 0, avgGreen = 0, avgBlue = 0; int count = 0; //取周围的像素 for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++) { for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++) { Color pixel = newbitmap.GetPixel(x, y); avgRed += pixel.R; avgGreen += pixel.G; avgBlue += pixel.B; count++; } } //取平均值 avgRed = avgRed / count; avgBlue = avgBlue / count; avgGreen = avgGreen / count; //设置颜色 for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++) { for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++) { Color newColor = Color.FromArgb(avgRed, avgGreen, avgBlue); newbitmap.SetPixel(x, y, newColor); } } } } sw1.Stop(); label1.Text = sw1.ElapsedMilliseconds.ToString(); pbnewimage.Image = newbitmap.Clone() as Image; } }
扩散效果
基本步骤
类似于水墨在纸上的扩散。随机挑选一个临近的像素,将其设为自身颜色。
这里一定注意要随机取周围的像素。
效果图
实现算法
private void btnspread_Click(object sender, EventArgs e) { if (bitmap != null) { newbitmap = bitmap.Clone() as Bitmap; sw1.Reset(); sw1.Restart(); Color pixel; int red, green, blue; int flag = 0; for (int x = 0; x < newbitmap.Width; x++) { for (int y = 0; y < newbitmap.Height; y++) { Random ran = new Random(); int RankKey = ran.Next(-5, 5); if (x + RankKey >= newbitmap.Width || y + RankKey >= newbitmap.Height || x + RankKey < 0 || y + RankKey < 0) { flag = 1; continue; } pixel = newbitmap.GetPixel(x + RankKey, y + RankKey); red = (int)(pixel.R); green = (int)(pixel.G); blue = (int)(pixel.B); newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue)); } } sw1.Stop(); label1.Text = sw1.ElapsedMilliseconds.ToString(); pbnewimage.Image = newbitmap.Clone() as Image; } }