最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2014年08月15日 09:02:44   投稿:junjie  
這篇文章主要介紹了c#中實現(xiàn)圖片灰度化技術(shù)詳解,本文給出計算公式和實現(xiàn)代碼以及圖片例子,需要的朋友可以參考下

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

以前我們在做Web上的用戶注冊時,通常都會做一個驗證碼,大家都知道用來防止暴力注冊的,當(dāng)然提到驗證碼大家都知道C#里面有一個Bitmap類專門用來處理圖片的,好吧,這一篇我們從最簡單的“圖片灰度化”說起。

一:圖片灰度化

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

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

1.計算公式

下面我們該如何設(shè)置合理的灰度值呢?當(dāng)然還是用當(dāng)前的RGB為模板,然后對RGB乘以一個合理的權(quán)重就ok了

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

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

2.編程

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

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)前的像素點
      var color = bitmap.GetPixel(i, j);
 
      var gray = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);
 
      //重新設(shè)置當(dāng)前的像素點
      bitmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
    }
  }
 
  bitmap.Save(Environment.CurrentDirectory + "http://2.jpg");
}

3.改進(jìn)

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

C#里面有一個Stride屬性就可以用來獲取,很簡單吧。

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");
    }

相關(guān)文章

最新評論

安陆市| 敦煌市| 卢湾区| 海晏县| 桐柏县| 丹凤县| 罗山县| 永宁县| 衢州市| 江西省| 辛集市| 龙南县| 始兴县| 彝良县| 曲沃县| 尉犁县| 塔城市| 左贡县| 台北县| 千阳县| 遂宁市| 巫溪县| 始兴县| 枞阳县| 卓资县| 交口县| 临沧市| 沂源县| 固镇县| 明溪县| 甘泉县| 淅川县| 伽师县| 青浦区| 灵石县| 和硕县| 九江市| 台东市| 桐庐县| 松滋市| 西安市|