C#_ LockBits と UnlockBits メモ 01

画像を扱う時に LockBits を使った方がいいらしい。
ポインタに展開されている画像データを配列に入れて、変更して再度ポインタに戻す的な。

LockBits    :Bitmap をシステムメモリにロックする。
UnlockBits:システムメモリから Bitmap のロックを解除する。

 

--ソース概要--
・bitmap を LockBits でロック。
ピクセルデータを格納するバイト型配列を Scan0 を用いて用意。
Marshal.Copy で bitmap データをバイト型配列へコピー。
・バイト型配列へアクセスして操作。
Marshal.Copy でバイト型配列を bitmap データへコピー。↑の逆。
・bitmap を UnlockBits で解除。

コピペ。


    Bitmap img = Image.FromFile("./test.bmp") as Bitmap;
   
    PixelFormat pixelFormat = img.PixelFormat;
   
    int pixelSize = Image.GetPixelFormatSize(pixelFormat) / 8;
    // 指定したピクセル形式の色深度 ( 1 ピクセルあたりのビットの数 ) を返す。
    // 24 bit ならば、8 で割ると R G B の 3 色。
   
    // 例外処理 略 throw new ArgumentException( "24 or 32 bit のみ有効"
   
    //Bitmapをロック
    BitmapData bmpData = img.LockBits(
        new Rectangle(0, 0, img.Width, img.Height),
        ImageLockMode.ReadWrite,
        pixelFormat);
   
    // 例外処理 略 if (bmpData.Stride < 0) { } throw ~ ボトムアップには非対応
    // Stride:1 ラインあたりのバイト数
    
    //ピクセルデータバイト型配列で取得
    IntPtr ptr = bmpData.Scan0; // Scan0:最初のピクセルでータアドレス
    byte[ ] pixels = new byte[bmpData.Stride * img.Height];
   
    // Bitmap を byte [ ] へコピー
    System.Runtime.InteropServices.Marshal.Copy(ptr, pixels, 0, pixels.Length);
   
    //すべてのピクセルの色を反転
    for (int y = 0; y < bmpData.Height; y++)
    {
        for (int x = 0; x < bmpData.Width; x++)
        {
            //ピクセルデータでのピクセル ( x , y ) の開始位置を計算
            int pos = y * bmpData.Stride + x * pixelSize;
            //青、緑、赤の色を変更
            pixels[pos] = (byte)(255 - pixels[pos]);
            pixels[pos + 1] = (byte)(255 - pixels[pos + 1]);
            pixels[pos + 2] = (byte)(255 - pixels[pos + 2]);
        }
    }
   
    //ピクセルデータを元に戻す。↑の逆
    System.Runtime.InteropServices.Marshal.Copy(pixels, 0, ptr, pixels.Length);
   
    //ロックを解除する
    img.UnlockBits(bmpData);
   
    pictureBox1.Image = img;

例外発生時にメモリリークを避けるため、
UnlockBits は tyr catch の finally に書く。

 

 

 

こちらから。
https://dobon.net/vb/dotnet/graphics/drawnegativeimage.html

以上。