成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳細介紹C# BitmapData

開發 后端
本文介紹C# BitmapData,對于C# BitmapData,雖然BitmapData.Width還是等于Bitmap.Width,但大概是出于顯示性能的考慮。

最近要轉開發平臺,正研究C#。C#好是好,不過處理圖片時一個像素一個像素的操作像素不是一般的慢。其實Delphi也一樣,但好在Delphi的Bitmap類提供了ScanLines,可以一行一行的讀圖,效率比較高。C#應該也有類似的東東。經過一番搜索,終于發現了C# BitmapData類。

先看個例子,這是對一張位圖的每個像素按FF取補,然后輸出到一個新圖(代碼有點啰嗦,不過應該可以說明問題了)。

  1. int h = m_Bmp.Height;  
  2. int w = m_Bmp.Width;  
  3.  
  4. Bitmap bmpOut = new Bitmap(w, h, PixelFormat.Format24bppRgb);  
  5.  
  6. BitmapData dataIn = m_Bmp.LockBits(new Rectangle(0,0,w,h),
    ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);  
  7. BitmapData dataOut = bmpOut.LockBits(new Rectangle(0, 0, w, h), 
    ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);  
  8.  
  9. unsafe  
  10. {  
  11. byte* pIn = (byte*)(dataIn.Scan0.ToPointer());  
  12. byte * pOut = (byte*)(dataOut.Scan0.ToPointer());  
  13.  
  14. for (int y = 0; y < dataIn.Height; y++)  
  15. {  
  16. for (int x = 0; x < dataIn.Width; x++)  
  17. {  
  18.  
  19. pOut[0] = (byte)(255 - pIn[0]);  
  20. pOut[1] = (byte)(255 - pIn[1]);  
  21. pOut[2] = (byte)(255 - pIn[2]);  
  22.  
  23. pIn += 3;  
  24. pOut += 3;  
  25. }  
  26.  
  27. pIn += dataIn.Stride - dataIn.Width * 3;  
  28. pOut += dataOut.Stride - dataOut.Width * 3;  
  29. }  
  30. }  
  31.  
  32. bmpOut.UnlockBits(dataOut);  
  33. m_Bmp.UnlockBits(dataIn); 

貌似比Delphi復雜得多,難道我真的天生對指針過敏?還是Delphi的比較好理解,就是掃描每一行,然后對當前像素點的三個分量做處理,非常方便。而且C#代碼中的Stride是個什么東東?

查找了不少資料,現在我是這么理解的:假設有一張圖片寬度為6,因為是Format24bppRgb格式(每像素3字節。在以下的討論中,除非特別說明,否則Bitmap都被認為是24位RGB)的,顯然,每一行需要6*3=18個字節存儲。對于Bitmap就是如此。但對于C# BitmapData,雖然BitmapData.Width還是等于Bitmap.Width,但大概是出于顯示性能的考慮,每行的實際的字節數將變成大于等于它的那個離它最近的4的整倍數,此時的實際字節數就是Stride.就此例而言,18不是4的整倍數,而比18大的離18最近的4的倍數是20,所以這個BitmapData.Stride = 20.顯然,當寬度本身就是4的倍數時,BitmapData.Stride = Bitmap.Width * 3.畫個圖可能更好理解。R、G、B 分別代表3個原色分量字節,BGR就表示一個像素。為了看起來方便我在每個像素之間插了個空格,實際上是沒有的。X表示補足4的倍數而自動插入的字節。為了符合人類的閱讀習慣我分行了,其實在計算機內存中應該看成連續的一大段。

現在應該很好理解了。首先用 BitmapData.Scan0找到第0個像素的第0個分量的地址。

這個地址指向的是個byte類型,所以當時定義為byte* pIn。
行掃描時,在當前指針位置(不妨看成當前像素的第0個顏色分量)連續取出三個值(3個原色分量。注意,0 1 2代表的次序是B G R。在取指針指向的值時,貌似p[n]和p += n再取p[0]是等價的),然后下移3個位置(pIn += 3,看成指到下一個像素的第0個顏色分量)。做過Bitmap.Width次操作后,就到達了Bitmap.Width * 3的位置,應該要跳過圖中標記為X的字節了(共有Stride - Width * 3個字節),代碼中就是 pIn += dataIn.Stride - dataIn.Width * 3;

跳過以后指針就到達下行的第0個像素了。按照此算法,一共需要做Bitmap.Height次行掃描(代碼就是 for (int y = 0; y < dataIn.Height; y++))。

另外,因為使用了unsafe,所以編譯的時候需要設置“允許不安全的代碼”。以上介紹C# BitmapData

【編輯推薦】

  1. 簡單介紹C#預處理
  2. 學習C#無詞尾符號經驗談
  3. C#調用QuickTest自動化
  4. 詳解C#正規表達式
  5. C#字符串插入html標簽
責任編輯:佚名 來源: IT168
相關推薦

2009-08-12 15:34:40

C# DBNull

2009-08-07 16:10:20

C#調用API

2009-08-26 17:31:59

C# const常量

2009-08-03 18:49:17

C#和Java

2009-08-21 15:16:23

C#使用指針

2009-08-20 15:26:42

C#循環語句

2009-08-24 18:21:23

C# ListView

2009-08-21 09:23:11

C# GDI+

2009-08-14 17:04:50

C#類型系統

2009-08-13 13:38:30

C#命名規范

2009-08-27 14:32:15

C#編寫ActiveX

2009-08-06 14:59:36

C#編譯器

2009-08-25 17:28:23

C#創建DataSet

2009-08-13 15:40:28

C#基礎知識

2011-06-08 13:35:18

C#數據類型

2009-08-27 17:31:44

C#創建Windows

2009-08-13 16:02:29

C#結構

2009-08-28 17:45:19

C#自定義數據

2011-07-14 11:08:30

C#繼承

2009-08-28 13:03:55

C#壓縮Access數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品中文字幕一区二区三区 | 狠狠干天天干 | 亚洲免费大片 | 91精品欧美久久久久久久 | 99在线观看视频 | 亚洲成av人片在线观看 | 在线成人免费av | 91久久久久| 国产精品成人一区二区三区夜夜夜 | 在线免费观看色 | 亚洲一二三区精品 | 黄色一级大片在线免费看产 | 午夜私人影院在线观看 | 国产高清在线视频 | 亚洲精品资源 | 久久久蜜桃 | 精品一区二区观看 | 精品日韩一区 | 欧美在线观看一区 | 暴草美女 | 亚洲美女天堂网 | 91久久久久久 | 青青草视频网 | 日本三级视频 | 老头搡老女人毛片视频在线看 | 欧美激情一区二区三区 | 精品免费国产 | av一区二区在线观看 | 欧美一级二级在线观看 | 亚洲精品99| 久久国内精品 | 精品欧美乱码久久久久久 | 国产成人免费视频网站高清观看视频 | 九九热精品视频 | 午夜一区二区三区在线观看 | 国产一二三区电影 | 色久伊人 | 国产欧美综合在线 | 亚洲一区中文 | 日本一二区视频 | 久久久久亚洲精品 |