注意:画像の表示方法が分からないという方は、まず「コントロールやフォームに画像を表示する」をご覧ください。
グレースケールとは、白から黒までの明暗(つまり、灰色の濃淡)だけで画像を表現する方法です。
「< グレースケール > Le Premier Soleil」によると、画像をグレースケールに変換する方法はいくつかありますが、ここではNTSC規格の白黒テレビなどで使われているYIQのYコンポーネントを使用することにします。
早速ですが、ColorMatrixクラスを使用して、指定した画像からグレースケール画像を作成する例を示します。このコードはフォームクラスに書かれており、フォームにはPictureBoxコントロール(PictureBox1)が配置されているものとします。PictureBox1をクリックすると、画像ファイル(C:\test\1.bmp)をグレースケールに変換した画像が表示されます。
なおColorMatrixクラスについては、「画像のカラーバランスを補正して表示する」で詳しく説明しています。また、ColorMatrixクラス以外の方法でグレースケールに変換することもできますが、その方法についてもそちらを参考にしてください。
'Imports System.Drawing ''' <summary> ''' 指定した画像からグレースケール画像を作成する ''' </summary> ''' <param name="img">基の画像</param> ''' <returns>作成されたグレースケール画像</returns> Public Shared Function CreateGrayscaleImage(ByVal img As Image) As Image 'グレースケールの描画先となるImageオブジェクトを作成 Dim newImg As New Bitmap(img.Width, img.Height) 'newImgのGraphicsオブジェクトを取得 Dim g As Graphics = Graphics.FromImage(newImg) 'ColorMatrixオブジェクトの作成 'グレースケールに変換するための行列を指定する Dim cm As New System.Drawing.Imaging.ColorMatrix( _ New Single()() { _ New Single() {0.299F, 0.299F, 0.299F, 0, 0}, _ New Single() {0.587F, 0.587F, 0.587F, 0, 0}, _ New Single() {0.114F, 0.114F, 0.114F, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1} _ }) 'ImageAttributesオブジェクトの作成 Dim ia As New System.Drawing.Imaging.ImageAttributes() 'ColorMatrixを設定する ia.SetColorMatrix(cm) 'ImageAttributesを使用してグレースケールを描画 g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), _ 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia) 'リソースを解放する g.Dispose() Return newImg End Function 'PictureBox1のClickイベントハンドラ Private Sub PictureBox1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles PictureBox1.Click 'グレースケールにする画像 Dim img As New Bitmap("C:\test\1.bmp") 'グレースケールに変換 Dim glayImg As Image = CreateGrayscaleImage(img) img.Dispose() 'PictureBox1に表示 If Not PictureBox1.Image Is Nothing Then PictureBox1.Image.Dispose() End If PictureBox1.Image = glayImg End Sub
//using System.Drawing; /// <summary> /// 指定した画像からグレースケール画像を作成する /// </summary> /// <param name="img">基の画像</param> /// <returns>作成されたグレースケール画像</returns> public static Image CreateGrayscaleImage(Image img) { //グレースケールの描画先となるImageオブジェクトを作成 Bitmap newImg = new Bitmap(img.Width, img.Height); //newImgのGraphicsオブジェクトを取得 Graphics g = Graphics.FromImage(newImg); //ColorMatrixオブジェクトの作成 //グレースケールに変換するための行列を指定する System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix( new float[][]{ new float[]{0.299f, 0.299f, 0.299f, 0 ,0}, new float[]{0.587f, 0.587f, 0.587f, 0, 0}, new float[]{0.114f, 0.114f, 0.114f, 0, 0}, new float[]{0, 0, 0, 1, 0}, new float[]{0, 0, 0, 0, 1} }); //ImageAttributesオブジェクトの作成 System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes(); //ColorMatrixを設定する ia.SetColorMatrix(cm); //ImageAttributesを使用してグレースケールを描画 g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia); //リソースを解放する g.Dispose(); return newImg; } //PictureBox1のClickイベントハンドラ private void PictureBox1_Click(object sender, EventArgs e) { //グレースケールにする画像 Bitmap img = new Bitmap(@"C:\test\1.bmp"); //グレースケールに変換 Image glayImg = CreateGrayscaleImage(img); img.Dispose(); //PictureBox1に表示 if (PictureBox1.Image != null) { PictureBox1.Image.Dispose(); } PictureBox1.Image = glayImg; }
結果は、次のようになります。上が元の画像で、下がグレースケールにした画像です。
「Matrix Operations for Image Processing」によると、上記のYIQの方法はガンマ値が2.2の時に最適であり、そうでない時は0.3086、0.6094、0.0820という値を使った方がよいということです。
この値にして上記のメソッドを書き直すと、次のようになります。
'Imports System.Drawing ''' <summary> ''' 指定した画像からグレースケール画像を作成する ''' </summary> ''' <param name="img">基の画像</param> ''' <returns>作成されたグレースケール画像</returns> Public Shared Function CreateGrayscaleImage(ByVal img As Image) As Image 'グレースケールの描画先となるImageオブジェクトを作成 Dim newImg As New Bitmap(img.Width, img.Height) 'newImgのGraphicsオブジェクトを取得 Dim g As Graphics = Graphics.FromImage(newImg) 'ColorMatrixオブジェクトの作成 'グレースケールに変換するための行列を指定する Dim cm As New System.Drawing.Imaging.ColorMatrix(New Single()() _ {New Single() {0.3086F, 0.3086F, 0.3086F, 0, 0}, _ New Single() {0.6094F, 0.6094F, 0.6094F, 0, 0}, _ New Single() {0.082F, 0.082F, 0.082F, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) 'ImageAttributesオブジェクトの作成 Dim ia As New System.Drawing.Imaging.ImageAttributes() 'ColorMatrixを設定する ia.SetColorMatrix(cm) 'ImageAttributesを使用してグレースケールを描画 g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), _ 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia) 'リソースを解放する g.Dispose() Return newImg End Function
//using System.Drawing; /// <summary> /// 指定した画像からグレースケール画像を作成する /// </summary> /// <param name="img">基の画像</param> /// <returns>作成されたグレースケール画像</returns> public static Image CreateGrayscaleImage(Image img) { //グレースケールの描画先となるImageオブジェクトを作成 Bitmap newImg = new Bitmap(img.Width, img.Height); //newImgのGraphicsオブジェクトを取得 Graphics g = Graphics.FromImage(newImg); //ColorMatrixオブジェクトの作成 //グレースケールに変換するための行列を指定する System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix( new float[][]{ new float[]{0.3086f, 0.3086f, 0.3086f, 0 ,0}, new float[]{0.6094f, 0.6094f, 0.6094f, 0, 0}, new float[]{0.0820f, 0.0820f, 0.0820f, 0, 0}, new float[]{0, 0, 0, 1, 0}, new float[]{0, 0, 0, 0, 1} }); //ImageAttributesオブジェクトの作成 System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes(); //ColorMatrixを設定する ia.SetColorMatrix(cm); //ImageAttributesを使用してグレースケールを描画 g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia); //リソースを解放する g.Dispose(); return newImg; }
結果は、次のようになります。上の画像が書き直した方法によるもので、下の画像が以前の方法によるものです。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。