程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c#中完成圖片灰度化技巧詳解

c#中完成圖片灰度化技巧詳解

編輯:C#入門知識

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved