C# - 影像處理

C# - 影像處理

練習使用 BitmapData 讀取影像,並在 C# 使用 IntPtr 指標形態,並在 unsafe 區塊中處理指標,進行相對應的影像處理。

讀取圖片:

讀取圖片

灰階:

(1) Gray = ( R + G + B ) / 3

(2) Gray = 0.299 * R + 0.587 * G + 0.114 * B

灰階

紅色濾鏡:

紅色濾鏡

綠色濾鏡:

綠色濾鏡

藍色濾鏡:

藍色濾鏡

程式碼:

  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Windows.Forms;
  5. namespace WindowsApplication_checkBox
  6. {
  7. public partial class Form1 : Form
  8. {
  9. public Form1( )
  10. {
  11. InitializeComponent( );
  12. }
  13. private void button5_Click( object sender, EventArgs e)
  14. {
  15. OpenFileDialog ofd = new OpenFileDialog( );
  16. ofd.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF";
  17. if (ofd.ShowDialog ( ) == DialogResult.OK )
  18. {
  19. pictureBox1.Image = Image.FromFile (ofd.FileName );
  20. }
  21. }
  22. private void button1_Click( object sender, EventArgs e)
  23. {
  24. Bitmap b = pictureBox1.Image as Bitmap;
  25. if (b == null )
  26. {
  27. MessageBox.Show ( "請載入圖片" );
  28. return;
  29. }
  30. int width = b.Width;
  31. int height = b.Height;
  32. BitmapData bd = b.LockBits ( new Rectangle( 0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb );
  33. IntPtr imgPtr = bd.Scan0;
  34. int stride = bd.Stride;
  35. int widthByte = width*3;
  36. int skipByte = stride - widthByte;
  37. int [,,] rgbData = new int [width,height,3 ];
  38. #region 讀取 RGB 資料
  39. unsafe
  40. {
  41. byte* p = ( byte*) ( void*) imgPtr;
  42. for ( int j = 0; j < height; j++)
  43. {
  44. for ( int i = 0; i < width; i++)
  45. {
  46. rgbData[i, j, 2 ] = p[ 0 ];
  47. p++;
  48. rgbData[i, j, 0 ] = p[ 0 ];
  49. p++;
  50. rgbData[i, j, 1 ] = p[ 0 ];
  51. p++;
  52. }
  53. p += skipByte;
  54. }
  55. }
  56. #endregion
  57. #region 灰階處理
  58. unsafe
  59. {
  60. imgPtr = bd.Scan0;
  61. byte* p = ( byte*) ( void*) imgPtr;
  62. for ( int j = 0; j < height; j++)
  63. {
  64. for ( int i = 0; i < width; i++)
  65. {
  66. int gary = (rgbData[i, j, 0 ] + rgbData[i, j, 1 ] + rgbData[i, j, 2 ] )/3;
  67. p[ 0 ] = ( byte ) gary;
  68. p++;
  69. p[ 0 ] = ( byte ) gary;
  70. p++;
  71. p[ 0 ] = ( byte ) gary;
  72. p++;
  73. }
  74. p += skipByte;
  75. }
  76. }
  77. #endregion
  78. b.UnlockBits (bd);
  79. Refresh( );
  80. }
  81. private void button2_Click( object sender, EventArgs e)
  82. {
  83. Bitmap b = pictureBox1.Image as Bitmap;
  84. if (b == null )
  85. {
  86. MessageBox.Show ( "請載入圖片" );
  87. return;
  88. }
  89. int width = b.Width;
  90. int height = b.Height;
  91. BitmapData bd = b.LockBits ( new Rectangle( 0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb );
  92. IntPtr imgPtr = bd.Scan0;
  93. int stride = bd.Stride;
  94. int widthByte = width*3;
  95. int skipByte = stride - widthByte;
  96. int [,,] rgbData = new int [width,height,3 ];
  97. #region 讀取 RGB 資料
  98. unsafe
  99. {
  100. byte* p = ( byte*) ( void*) imgPtr;
  101. for ( int j = 0; j < height; j++)
  102. {
  103. for ( int i = 0; i < width; i++)
  104. {
  105. rgbData[i, j, 2 ] = p[ 0 ];
  106. p++;
  107. rgbData[i, j, 0 ] = p[ 0 ];
  108. p++;
  109. rgbData[i, j, 1 ] = p[ 0 ];
  110. p++;
  111. }
  112. p += skipByte;
  113. }
  114. }
  115. #endregion
  116. #region 紅色濾鏡
  117. unsafe
  118. {
  119. imgPtr = bd.Scan0;
  120. byte* p = ( byte*) ( void*) imgPtr;
  121. for ( int j = 0; j < height; j++)
  122. {
  123. for ( int i = 0; i < width; i++)
  124. {
  125. p[ 0 ] = 0;
  126. p++;
  127. p[ 0 ] = 0;
  128. p++;
  129. p++;
  130. }
  131. p += skipByte;
  132. }
  133. }
  134. #endregion
  135. b.UnlockBits (bd);
  136. Refresh( );
  137. }
  138. private void button3_Click( object sender, EventArgs e)
  139. {
  140. Bitmap b = pictureBox1.Image as Bitmap;
  141. if (b == null )
  142. {
  143. MessageBox.Show ( "請載入圖片" );
  144. return;
  145. }
  146. int width = b.Width;
  147. int height = b.Height;
  148. BitmapData bd = b.LockBits ( new Rectangle( 0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb );
  149. IntPtr imgPtr = bd.Scan0;
  150. int stride = bd.Stride;
  151. int widthByte = width*3;
  152. int skipByte = stride - widthByte;
  153. int [,,] rgbData = new int [width,height,3 ];
  154. #region 讀取 RGB 資料
  155. unsafe
  156. {
  157. byte* p = ( byte*) ( void*) imgPtr;
  158. for ( int j = 0; j < height; j++)
  159.