[C#] 濾鏡筆記 – 動態模糊化、馬賽克 影像處理
2012-12-11
其實模糊化跟馬賽克效果其實原理很像…
他其實是取一定範圍內的 R , G , B 均值之後寫回原本的 Pixel
正所謂跑一定均值就代表,要跑小迴圈,所以時間都會比較長一點
不過這是學習筆記,看一下他 Pixel 的 R G B 變化
模糊化:
/// <summary>
/// 調整圖片模糊化
/// </summary>
/// <param name="bitmap"></param>
/// <param name="effectRradius"> 模糊程度,取樣的範圍 </param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustTobBlur(System.Drawing.Bitmap bitmap, int effectRradius)
{
// 整體圖片跑 Pixel 迴圈
for (int heightOffset = 0; heightOffset < bitmap.Height; heightOffset++)
{
for (int widthOffset = 0; widthOffset < bitmap.Width; widthOffset++)
{
// 負責計算平均值
int avgR = 0, avgG = 0, avgB = 0;
int blurPixelCount = 0;
// 計算傳入影響範圍內 的 RGB 平均
for (int x = widthOffset; (x < widthOffset + effectRradius && x < bitmap.Width); x++)
{
for (int y = heightOffset; (y < heightOffset + effectRradius && y < bitmap.Height); y++)
{
System.Drawing.Color pixel = bitmap.GetPixel(x, y);
avgR += pixel.R;
avgG += pixel.G;
avgB += pixel.B;
blurPixelCount++;
}
}
// 計算個別平均
avgR = avgR / blurPixelCount;
avgG = avgG / blurPixelCount;
avgB = avgB / blurPixelCount;
// 寫回入新圖片
for (int x = widthOffset; (x < widthOffset + effectRradius && x < bitmap.Width); x++)
{
for (int y = heightOffset; (y < heightOffset + effectRradius && y < bitmap.Height); y++)
{
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(avgR, avgG, avgB);
bitmap.SetPixel(x, y, newColor);
}
}
}
}
return bitmap;
}
每一個 Pixel 都會依照你傳入的 effectRadius 取跑小迴圈進行取樣採平均值
所以之後會在跑一次迴圈個別寫入平均…
測試結果:
var img = AdjustTobBlur(bitmap, 5);
var img = AdjustTobBlur(bitmap, 10);
如果矩陣作法可以參考這一篇 速度會快很多 : http://haishibai.blogspot.tw/2009/09/image-processing-c-tutorial-4-gaussian.html
馬賽克的作法 其實很像 只是 他會在範圍內的所有 RGB 設成一定均質..
C# Code:
/// <summary>
/// 馬賽克處理
/// </summary>
/// <param name="bitmap"></param>
/// <param name="effectWidth"> 影響範圍 每一個格子數 </param>
/// <returns></returns>
public System.Drawing.Bitmap AdjustTobMosaic(System.Drawing.Bitmap bitmap, int effectWidth)
{
// 差異最多的就是以照一定範圍取樣 玩之後直接去下一個範圍
for (int heightOfffset = 0; heightOfffset < bitmap.Height; heightOfffset += effectWidth)
{
for (int widthOffset = 0; widthOffset < bitmap.Width; widthOffset += effectWidth)
{
int avgR = 0, avgG = 0, avgB = 0;
int blurPixelCount = 0;
for (int x = widthOffset; (x < widthOffset + effectWidth && x < bitmap.Width); x++)
{
for (int y = heightOfffset; (y < heightOfffset + effectWidth && y < bitmap.Height); y++)
{
System.Drawing.Color pixel = bitmap.GetPixel(x, y);
avgR += pixel.R;
avgG += pixel.G;
avgB += pixel.B;
blurPixelCount++;
}
}
// 計算範圍平均
avgR = avgR / blurPixelCount;
avgG = avgG / blurPixelCount;
avgB = avgB / blurPixelCount;
// 所有範圍內都設定此值
for (int x = widthOffset; (x < widthOffset + effectWidth && x < bitmap.Width); x++)
{
for (int y = heightOfffset; (y < heightOfffset + effectWidth && y < bitmap.Height); y++)
{
System.Drawing.Color newColor = System.Drawing.Color.FromArgb(avgR, avgG, avgB);
bitmap.SetPixel(x, y, newColor);
}
}
}
}
return bitmap;
}
結果:
var img = AdjustTobMosaic(bitmap, 10);
var img = AdjustTobMosaic(bitmap, 5);
馬賽克速度還可以 但是模糊化如果要產品使用真的要改寫..
參考:
http://notes.ericwillis.com/2009/10/blur-an-image-with-csharp/