原文鏈接: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; } }