Skip to content

Instantly share code, notes, and snippets.

@nissuk
Created March 26, 2011 20:17
Show Gist options
  • Save nissuk/888601 to your computer and use it in GitHub Desktop.
Save nissuk/888601 to your computer and use it in GitHub Desktop.
System.Drawing.Bitmapをグレースケール変換するメソッドの例
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Partial Public Class ImageProcessing
''' <summary>
''' Bitmapからグレースケール化されたBitmapを生成します。
''' </summary>
''' <param name="image">Bitmap</param>
''' <returns>グレースケール化されたBitmap</returns>
''' <remarks></remarks>
Public Shared Function ToGrayscale(ByVal image As Bitmap) As Bitmap
Dim rect As New Rectangle(Point.Empty, image.Size)
Dim pixel_format As PixelFormat = PixelFormat.Format24bppRgb
Dim pixel_format_size As Integer = Drawing.Image.GetPixelFormatSize(pixel_format) \ 8
' 1. 元画像のBitmapオブジェクトのピクセルデータを配列にコピーします。
Dim data As BitmapData = image.LockBits( _
rect, ImageLockMode.ReadOnly, pixel_format)
Dim stride As Integer = Math.Abs(data.Stride)
Dim bytes(stride * data.Height - 1) As Byte
Marshal.Copy(data.Scan0, bytes, 0, bytes.Length)
image.UnlockBits(data)
' 2. すべてのピクセルをグレースケールに変換します。
Dim y_last As Integer = data.Height - 1
Dim x_last As Integer = data.Width - 1
For y As Integer = 0 To y_last
For x As Integer = 0 To x_last
Dim i As Integer = y * stride + x * pixel_format_size
Dim r As Byte = bytes(i + 2)
Dim g As Byte = bytes(i + 1)
Dim b As Byte = bytes(i)
Dim gray As Byte = CByte(r * 0.29891 + g * 0.58661 + b * 0.11448)
bytes(i + 2) = gray
bytes(i + 1) = gray
bytes(i) = gray
Next
Next
' 3. 新しいBitmapオブジェクトに、
' グレースケール変換したピクセルデータをコピーします。
Dim result As New Bitmap(image.Width, image.Height, pixel_format)
Dim result_data As BitmapData = result.LockBits( _
rect, ImageLockMode.WriteOnly, pixel_format)
Marshal.Copy(bytes, 0, result_data.Scan0, bytes.Length)
result.UnlockBits(result_data)
Return result
End Function
End Class
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Partial Public Class ImageProcessing
''' <summary>
''' Bitmapから8bitインデックスカラーのグレースケール化されたBitmapを生成します。
''' 高速ですがこのままだとGraphics.FromImage()で使えません。
''' </summary>
''' <param name="image">Bitmap</param>
''' <returns>グレースケール化されたBitmap</returns>
''' <remarks></remarks>
Public Shared Function To8bppIndexedGrayscale(ByVal image As Bitmap) As Bitmap
Dim rect As New Rectangle(Point.Empty, image.Size)
Dim pixel_format As PixelFormat = PixelFormat.Format24bppRgb
' 1. 新しいBitmapオブジェクト(8bitインデックスカラー)を生成して
' カラーパレットをすべてグレースケール化します。
Dim result As New Bitmap(image.Width, image.Height, PixelFormat.Format8bppIndexed)
Dim palette As ColorPalette = result.Palette
For i As Integer = 0 To 255
palette.Entries(i) = Color.FromArgb(i, i, i)
Next
result.Palette = palette
' 2. 元画像のBitmapオブジェクトのピクセルデータを配列にコピーします。
Dim data As BitmapData = image.LockBits( _
rect, ImageLockMode.ReadOnly, pixel_format)
Dim bytes(data.Stride * data.Height - 1) As Byte
Marshal.Copy(data.Scan0, bytes, 0, bytes.Length)
image.UnlockBits(data)
' 3. 新しいBitmapオブジェクトにピクセルデータをコピーします。
Dim result_data As BitmapData = result.LockBits( _
rect, ImageLockMode.WriteOnly, pixel_format)
Marshal.Copy(bytes, 0, result_data.Scan0, bytes.Length)
result.UnlockBits(result_data)
Return result
End Function
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment