以下の例は、BitmapクラスのLockBits/UnlockBitsメソッドの呼び出しをラップするクラスBitmapLockを作成し、usingステートメントで使用できるようにしたものです。 この例では、画像ファイルorigin.pngを読み込み、色を反転した結果をnegated.pngとして保存しています。
LockBits/UnlockBitsの呼び出しをラップしてusingステートメントで使えるようにする
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
' Bitmap.LockBits/UnlockBitsの処理をラップしたクラス
Class BitmapLock
Implements IDisposable
Private bitmap As Bitmap
Private data As BitmapData
Public Sub New(ByVal bitmap As Bitmap, ByVal rect As Rectangle, ByVal mode As ImageLockMode, ByVal format As PixelFormat)
MyClass.bitmap = bitmap
MyClass.data = bitmap.LockBits(rect, mode, format)
End SUb
Public Sub Dispose() Implements IDisposable.Dispose
If Not data is Nothing Then
bitmap.UnlockBits(data)
data = Nothing
bitmap = Nothing
End If
End Sub
' ラインyの先頭のポインタを取得する
Public Function GetScanLine(ByVal y As Integer) As IntPtr
If data Is Nothing Then Throw New ObjectDisposedException(Me.GetType().FullName)
Return New IntPtr(data.Scan0.ToInt32() + y * data.Stride)
End Function
End Class
Class Sample
Shared Sub Main()
Using bitmap As Bitmap = DirectCast(Image.FromFile("origin.png"), Bitmap)
Dim rect As New Rectangle(0, 0, bitmap.Width, bitmap.Height)
' 画像全体のピクセルを読み書きできるようにロックする
Using locked As New BitmapLock(bitmap, rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
For y As Integer = 0 To rect.Height - 1
Dim line As IntPtr = locked.GetScanLine(y)
For x As Integer = 0 To rect.Width - 1
' 1ピクセル分読み込み
Dim col As Integer = Marshal.ReadInt32(line, x * 4)
' 反転した値を書き込む
Marshal.WriteInt32(line, x * 4, Not col)
Next
Next
End Using
bitmap.Save("negated.png", ImageFormat.Png)
End Using
End Sub
End Class