c#中完成圖片灰度化技巧詳解。本站提示廣大學習愛好者:(c#中完成圖片灰度化技巧詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是c#中完成圖片灰度化技巧詳解正文
客歲買了本數字圖象處置算法,一向都沒有看,前幾個禮拜都一向忙著任務上的活,趁這階段安閒點,玩一玩圖片處置,這玩意照樣異常成心思的。
之前我們在做Web上的用戶注冊時,平日都邑做一個驗證碼,年夜家都曉得用來避免暴力注冊的,固然提到驗證碼年夜家都曉得C#外面有一個Bitmap類專門用來處置圖片的,好吧,這一篇我們從最簡略的“圖片灰度化”說起。
一:圖片灰度化
我們都曉得,位圖是由一個一個像素點構成的,像素點能夠是白色,橙色,粉色等等,這些色彩我們都曉得是用RGB來表現的。
每一個色彩重量都是一個字節(0-255),所以普通情形下圖的像素點都是24位,固然還有32位,64位,當RGB是0-255之間的分歧值時,那末該像素點就出現“五彩缤紛”,而當RGB都是雷同的值是,則像素點出現“灰色”,假如年夜家玩過CSS的話,確定都曉得給一個字體的color平日都是#999999,#666666,#333333這些分歧深度的灰色。
1.盤算公式
上面我們該若何設置公道的灰度值呢?固然照樣用以後的RGB為模板,然後對RGB乘以一個公道的權重就ok了
Gary(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.114*B(i,j);
2.編程
有了公式,完成起來就不成成績了。Bitmap類中有一個GetPixel/SetPixel,它可以獲得和設置以後的像素點。
static void Main(string[] args)
{
Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg");
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
//取圖片以後的像素點
var color = bitmap.GetPixel(i, j);
var gray = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);
//從新設置以後的像素點
bitmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
}
}
bitmap.Save(Environment.CurrentDirectory + "//2.jpg");
}

3.改良
下面這個辦法很簡略,Get/Set就Ok了,固然這是我們站在像素點這個角度來斟酌成績的,貌似只需O(N2)的時光便可以KO成績,然則Get/Set遠遠不是O(1)的,基於機能斟酌,我們能不克不及有更優的辦法,此時我們可以站在字節這個角度思慮,不外這裡我們要留意一個成績就是:好比圖片的width=21px,一個像素點占用3個字節,然則21個像素點紛歧定就占用63個字節,這是由於體系基於機能斟酌,在每行中寄存著一個“未用區域”,來確保圖片每行的byte數是4的倍數,那末若何去讀某一行的字節數呢?
C#外面有一個Stride屬性便可以用來獲得,很簡略吧。
static void Main(string[] args)
{
Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg");
//界說鎖定bitmap的rect的指定規模區域
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
//加鎖區域像素
var bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
//位圖的首地址
var ptr = bitmapData.Scan0;
//stride:掃描行
int len = bitmapData.Stride * bitmap.Height;
var bytes = new byte[len];
//鎖定區域的像素值copy到byte數組中
Marshal.Copy(ptr, bytes, 0, len);
for (int i = 0; i < bitmap.Height; i++)
{
for (int j = 0; j < bitmap.Width * 3; j = j + 3)
{
var color = bytes[i * bitmapData.Stride + j + 2] * 0.299
+ bytes[i * bitmapData.Stride + j + 1] * 0.597
+ bytes[i * bitmapData.Stride + j] * 0.114;
bytes[i * bitmapData.Stride + j]
= bytes[i * bitmapData.Stride + j + 1]
= bytes[i * bitmapData.Stride + j + 2] = (byte)color;
}
}
//copy回位圖
Marshal.Copy(bytes, 0, ptr, len);
//解鎖
bitmap.UnlockBits(bitmapData);
bitmap.Save(Environment.CurrentDirectory + "//3.jpg");
}
