ブログ技術

【WPF】WriteableBitmap クラスでbitmapイメージを操作する

 

 

 

概要

 

WPFはbitmapクラスから派生したさまざまなクラスがありますが、WriteableBitmapクラスを使用するとWindowsながら画素を直接操作するという低レベルプログラミングが可能になります。

WriteableBitmapクラスを使って画面をピクセル単位に操作してみました。

 

 

 

環境

 

Microsoft Visual Studio 2015 + WPF + VB

 

 

 

WriteableBitmapクラス

 

 

以下のプロパティまたはメソッドを使用しました。

 

BackBuffer
画面に対応するバッファのポインタを取得する

 

BackBufferStride
画面一行のバッファサイズを取得する

 

Lock
画面をロックする(バッファを編集中)

 

Unlock
画面をアンロックする(バッファ編集を終了)

 

AddDirtyRect
画面の更新対象領域を指定する(指定された領域のみ更新される)

 

 

※コピー&ペーストはbitmapsourceクラス(親クラス)のCopyPixelsとWritePixcelsというメソッドを利用しています。画面のビットマップイメージデータを指定のバッファへのコピーしたりバッファのビットマップイメージデータを画面に出力できます。

 

 

 

サンプル

 

スクリプト

 

矩形領域をコピー

Private copiedBmpArray() As Byte
・
・

    Dim x As Integer = コピー対象矩形左上X座標
    Dim y As Integer = コピー対象矩形左上Y座標
    Dim w As Integer = コピー対象矩形横幅
    Dim h As Integer = コピー対象矩形高さ
    Dim datasize As Integer
    rem 必要なサイズを確保する
    datasize = バッファデータサイズ

    copiedBmpArray = New Byte(datasize) {}

    rem 選択した矩形をバッファに保存する
    bitmapWrtable.CopyPixels(New Int32Rect(x, y, w, h), _
                             copiedBmpArray, _
                             bitmapWrtable.BackBufferStride, _
                             0)

 

ペースト

    Dim x As Integer = ペースト先矩形左上X座標
    Dim y As Integer = ペースト先矩形左上Y座標
    Dim w As Integer = ペースト先矩形横幅
    Dim h As Integer = ペースト先矩形高さ


    '選択した矩形を指定領域に出力する
    bitmapWrtable.WritePixels(New Int32Rect(x, y, w, h), _
                              copiedBmpArray, _
                              bitmapWrtable.BackBufferStride, _
                              0)

 

画素を直接操作(領域クリア)

    '画面に対応するバッファのポインタを取得する    
    Dim pntWrt As IntPtr
    pntWrt = bitmapWrtable.BackBuffer
    '画面の一行のバイト数を取得する
    Dim bufst As Integer = bitmapWrtable.BackBufferStride
    'ロックする
    bitmapWrtable.Lock()

    For lopy As Integer = y1 To y2

        For lopx As Integer = x1 To x2
            '書込みポイントの算出
             offadrWrt = (lopy * bufst) + lopx * elementSize

             '対象の画素に0を書き込む(クリアする)
             Marshal.WriteInt32(pntWrt, offadrWrt, CType(0, Int32))
        Next lopx
    Next lopy
    '変更する対象の領域をシステムに通知する(この領域だけ更新の対象になる)
    bitmapWrtable.AddDirtyRect(New Int32Rect(0, 0, bitmapWrtable.PixelWidth, bitmapWrtable.PixelHeight))

    'アンロックする
    bitmapWrtable.Unlock()

 

 

 

参考