国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C# > 正文

c#中實(shí)現(xiàn)圖片灰度化技術(shù)詳解

2020-01-24 02:31:48
字體:
供稿:網(wǎng)友

去年買了本數(shù)字圖像處理算法,一直都沒有看,前幾個(gè)星期都一直忙著工作上的活,趁這階段悠閑點(diǎn),玩一玩圖片處理,這玩意還是非常有意思的。

以前我們?cè)谧鯳eb上的用戶注冊(cè)時(shí),通常都會(huì)做一個(gè)驗(yàn)證碼,大家都知道用來防止暴力注冊(cè)的,當(dāng)然提到驗(yàn)證碼大家都知道C#里面有一個(gè)Bitmap類專門用來處理圖片的,好吧,這一篇我們從最簡(jiǎn)單的“圖片灰度化”說起。

一:圖片灰度化

我們都知道,位圖是由一個(gè)一個(gè)像素點(diǎn)組成的,像素點(diǎn)可能是紅色,橙色,粉色等等,這些顏色我們都知道是用RGB來表示的。

每個(gè)顏色分量都是一個(gè)字節(jié)(0-255),所以一般情況下圖的像素點(diǎn)都是24位,當(dāng)然還有32位,64位,當(dāng)RGB是0-255之間的不同值時(shí),那么該像素點(diǎn)就呈現(xiàn)“五顏六色”,而當(dāng)RGB都是相同的值是,則像素點(diǎn)呈現(xiàn)“灰色”,如果大家玩過CSS的話,肯定都知道給一個(gè)字體的color通常都是#999999,#666666,#333333這些不同深度的灰色。

1.計(jì)算公式

下面我們?cè)撊绾卧O(shè)置合理的灰度值呢?當(dāng)然還是用當(dāng)前的RGB為模板,然后對(duì)RGB乘以一個(gè)合理的權(quán)重就ok了

復(fù)制代碼 代碼如下:

   Gary(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.114*B(i,j);

2.編程

有了公式,實(shí)現(xiàn)起來就不成問題了。Bitmap類中有一個(gè)GetPixel/SetPixel,它可以獲取和設(shè)置當(dāng)前的像素點(diǎn)。

static void Main(string[] args){  Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "http://1.jpg");   for (int i = 0; i < bitmap.Width; i++)  {    for (int j = 0; j < bitmap.Height; j++)    {      //取圖片當(dāng)前的像素點(diǎn)      var color = bitmap.GetPixel(i, j);       var gray = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);       //重新設(shè)置當(dāng)前的像素點(diǎn)      bitmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));    }  }   bitmap.Save(Environment.CurrentDirectory + "http://2.jpg");}

3.改進(jìn)

上面這個(gè)方法很簡(jiǎn)單,Get/Set就Ok了,當(dāng)然這是我們站在像素點(diǎn)這個(gè)角度來考慮問題的,貌似只要O(N2)的時(shí)間就可以KO問題,但是Get/Set遠(yuǎn)遠(yuǎn)不是O(1)的,基于性能考慮,我們能不能有更優(yōu)的方法,此時(shí)我們可以站在字節(jié)這個(gè)角度思考,不過這里我們要注意一個(gè)問題就是:比如圖片的width=21px,一個(gè)像素點(diǎn)占用3個(gè)字節(jié),但是21個(gè)像素點(diǎn)不一定就占用63個(gè)字節(jié),這是因?yàn)橄到y(tǒng)基于性能考慮,在每一行中存放著一個(gè)“未用區(qū)域”,來確保圖片每行的byte數(shù)是4的倍數(shù),那么如何去讀某一行的字節(jié)數(shù)呢?

C#里面有一個(gè)Stride屬性就可以用來獲取,很簡(jiǎn)單吧。

static void Main(string[] args)    {      Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "http://1.jpg");       //定義鎖定bitmap的rect的指定范圍區(qū)域      Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);       //加鎖區(qū)域像素      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];       //鎖定區(qū)域的像素值copy到byte數(shù)組中      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 + "http://3.jpg");    }

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 连江县| 池州市| 巍山| 丹阳市| 健康| 武宁县| 堆龙德庆县| 灵山县| 彭泽县| 南乐县| 夹江县| 闽侯县| 明星| 平遥县| 巴彦淖尔市| 河间市| 旬邑县| 吉木乃县| 黎川县| 延边| 阳曲县| 于田县| 吉水县| 沐川县| 大英县| 华蓥市| 农安县| 清丰县| 清流县| 仙桃市| 英德市| 全州县| 鄂托克前旗| 绿春县| 吉首市| 栾川县| 湘乡市| 郴州市| 阳西县| 琼结县| 建水县|