DOBON.NETプログラミング道掲示板

ツリー一括表示

Nomalアイコン PIctureBox同士を論理合成したい /HIROPON (19/03/01(Fri) 22:07) #34177
Nomalアイコン Re[1]: PIctureBox同士を論理合成したい /魔界の仮面弁士 (19/03/01(Fri) 22:14) #34179
  └Nomalアイコン Re[2]: PIctureBox同士を論理合成したい /HIROPON (19/03/02(Sat) 18:48) #34180
    └Nomalアイコン Re[3]: PIctureBox同士を論理合成したい /HIROPON (19/03/08(Fri) 22:32) #34191 解決み!


親記事 / ▼[ 34179 ]
■34177 / 親階層)  PIctureBox同士を論理合成したい
□投稿者/ HIROPON 一般人(1回)-(2019/03/01(Fri) 22:07:14)
  • アイコン環境/言語:[Windows7 VB.NET2017] 
    分類:[.NET] 

    お世話になります。

    VB.NET 2017において、Picturebox同士の画像を論理合成したいのです。
    PictureBox1 = PictureBox1 AND PictureBox2
    みたいな感じです。
    ピクセル1個つづ読み取ってANDして描画してみましたが、速度的に使い物になりませんでした。
    ネットで調べてみましたが、透明色を設定して合成というのはありましたが、色には関係なく全面的に論理処理を行いたいのです。

    よろしくおねがいします。
違反を報告
[ □ Tree ] 返信 削除キー/

▲[ 34177 ] / ▼[ 34180 ]
■34179 / 1階層)  Re[1]: PIctureBox同士を論理合成したい
□投稿者/ 魔界の仮面弁士 大御所(1213回)-(2019/03/01(Fri) 22:14:09)
  • アイコンNo34177に返信(HIROPONさんの記事)
    > ピクセル1個つづ読み取ってANDして描画してみましたが、速度的に使い物になりませんでした。
    Bitmap.GetPixel / SetPixel メソッドでの書き換えは低速なので、
    大量のピクセルの色を変更する場合は、Bitmap.LockBits メソッドで得た
    BitmapData の Scan0 プロパティに対して読み書きするのが常套手段です。
    https://dobon.net/vb/dotnet/graphics/colorbalance.html#lockbits
    https://dobon.net/vb/dotnet/graphics/drawnegativeimage.html#lockbits
違反を報告
[ 親 34177 / □ Tree ] 返信 削除キー/

▲[ 34179 ] / ▼[ 34191 ]
■34180 / 2階層)  Re[2]: PIctureBox同士を論理合成したい
□投稿者/ HIROPON 一般人(2回)-(2019/03/02(Sat) 18:48:03)
  • アイコンご提示のサンプルを元に以下のようなメソッドを作ってみました。
    ------------------------------------------------------------
    Public Sub AddCopy(ByVal Srcimg As Bitmap, ByVal Desimg As Bitmap)

    '1ピクセルあたりのバイト数を取得する
    Dim SrcpixelFormat As PixelFormat = Srcimg.PixelFormat
    Dim SrcpixelSize As Integer = Image.GetPixelFormatSize(SrcpixelFormat) / 8
    If SrcpixelSize < 3 OrElse 4 < SrcpixelSize Then
    Throw New ArgumentException(
    "1ピクセルあたり24または32ビットの形式のイメージのみ有効です。",
    "Srcimg")
    End If

    Dim DespixelFormat As PixelFormat = Desimg.PixelFormat
    Dim DespixelSize As Integer = Image.GetPixelFormatSize(DespixelFormat) / 8
    If DespixelSize < 3 OrElse 4 < DespixelSize Then
    Throw New ArgumentException(
    "1ピクセルあたり24または32ビットの形式のイメージのみ有効です。",
    "Desimg")
    End If

    'Bitmapをロックする
    Dim SrcbmpDate As BitmapData =
    Srcimg.LockBits(New Rectangle(0, 0, Srcimg.Width, Srcimg.Height),
    ImageLockMode.ReadWrite, Srcimg.PixelFormat)

    If SrcbmpDate.Stride < 0 Then
    Srcimg.UnlockBits(SrcbmpDate)
    Throw New ArgumentException(
    "ボトムアップ形式のイメージには対応していません。",
    "Srcimg")
    End If

    Dim DesbmpDate As BitmapData =
    Desimg.LockBits(New Rectangle(0, 0, Desimg.Width, Desimg.Height),
    ImageLockMode.ReadWrite, Desimg.PixelFormat)

    If DesbmpDate.Stride < 0 Then
    Desimg.UnlockBits(DesbmpDate)
    Throw New ArgumentException(
    "ボトムアップ形式のイメージには対応していません。",
    "Desimg")
    End If

    'ピクセルデータをバイト型配列で取得する
    Dim Srcptr As IntPtr = SrcbmpDate.Scan0
    Dim Srcpixels As Byte() = New Byte(SrcbmpDate.Stride * Srcimg.Height - 1) {}
    System.Runtime.InteropServices.Marshal.Copy(Srcptr, Srcpixels, 0, Srcpixels.Length)

    Dim Desptr As IntPtr = DesbmpDate.Scan0
    Dim Despixels As Byte() = New Byte(DesbmpDate.Stride * Desimg.Height - 1) {}
    System.Runtime.InteropServices.Marshal.Copy(Desptr, Despixels, 0, Despixels.Length)

    'すべてのピクセルの色を補正する
    For y As Integer = 0 To SrcbmpDate.Height - 1
    For x As Integer = 0 To SrcbmpDate.Width - 1
    'ピクセルデータでのピクセル(x,y)の開始位置を計算する
    Dim Srcpos As Integer = y * SrcbmpDate.Stride + x * SrcpixelSize
    Dim Despos As Integer = y * DesbmpDate.Stride + x * DespixelSize

    '新しい色を計算する
    Dim SrcnewR As Integer = Srcpixels(Srcpos + 2)
    Dim SrcnewG As Integer = Srcpixels(Srcpos + 1)
    Dim SrcnewB As Integer = Srcpixels(Srcpos + 0)

    Dim DesnewR As Integer = Despixels(Despos + 2)
    Dim DesnewG As Integer = Despixels(Despos + 1)
    Dim DesnewB As Integer = Despixels(Despos + 0)

    Dim newR As Integer = SrcnewR And DesnewR
    Dim newG As Integer = SrcnewG And DesnewG
    Dim newB As Integer = SrcnewB And DesnewB

    '色を変更する
    Despixels(Srcpos + 2) = CByte(newR)
    Despixels(Srcpos + 1) = CByte(newG)
    Despixels(Srcpos) = CByte(newB)
    Next
    Next

    'ピクセルデータを元に戻す
    System.Runtime.InteropServices.Marshal.Copy(Despixels, 0, Desptr, Despixels.Length)

    'ロックを解除する
    Srcimg.UnlockBits(SrcbmpDate)
    Desimg.UnlockBits(DesbmpDate)

    End Sub
    ------------------------------------------------------------------------
    どうにか思い通りの結果が得られました。
    ありがとうございます。

違反を報告
[ 親 34177 / □ Tree ] 返信 削除キー/

▲[ 34180 ] / 返信無し
■34191 / 3階層)  Re[3]: PIctureBox同士を論理合成したい
□投稿者/ HIROPON 一般人(3回)-(2019/03/08(Fri) 22:32:56)
  • アイコン解決しました!
解決み!
違反を報告
[ 親 34177 / □ Tree ] 返信 削除キー/


Mode/  Pass/


- Child Tree -