Bitmapで

解決


マグ  2005-06-25 11:41:21  No: 123060  IP: [192.*.*.*]

開発環境:VB.NET + WindowsXP

PictureBox上に描かれているのをBitmapで定義した変数に渡したいのですが、
どのように記述すれば、いいか分かりません。

編集 削除
魔界の仮面弁士  2005-06-25 13:15:57  No: 123061  IP: [192.*.*.*]

PictureBoxのImageプロパティを、Bitmap型にキャストするとか。

編集 削除
マグ  2005-06-25 16:52:32  No: 123062  IP: [192.*.*.*]

簡易的に作って見たのですが、

PictureBox1.BackColor = Color.Red
Dim bit1 As Bitmap, bit2 As Bitmap
bit1 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
bit2 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
bit2 = CType(PictureBox1.Image, Bitmap)
PictureBox1.BackColor = Color.White
PictureBox1.Image = bit2

キャストが成功していれば、赤になるはずなのですが・・・・
なりません。
何処がおかしいのでしょうか?

編集 削除
ねろ  2005-06-25 17:51:12  No: 123063  IP: [192.*.*.*]

>何処がおかしいのでしょうか?
PictureBox1にどこでビットマップを読み込んでますか?
ブレークポイントでブレークして、bit1とbit2の値を見れば
ビットマップが読み込まれていないのが判りますが。
単にこれで良いのでは。
Dim bit1 As Bitmap
PictureBox1.Image = Image.FromFile("C:\test.bmp")
bit1 = PictureBox1.Image
PictureBox1.Image = Nothing
PictureBox1.Image = bit1
誤爆か?

編集 削除
夏の朝も天玉うどん  2005-06-25 18:58:25  No: 123064  IP: [192.*.*.*]

マグ様、直接には本題と関係ないかもしれませんがBackColorプロパティは、ここで言うImageには描画しません。以下のコード下の2行のどちらかをコメントアウトして確認してみてください。       
        PictureBox1.BackColor = Color.Red
        Dim lightPen As New Pen(Color.LightGray, 1)
        Dim bit1 As Bitmap, bit2 As Bitmap
        bit1 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        bit2 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        PictureBox1.Image = bit1
        Dim g = Graphics.FromImage(PictureBox1.Image)
        g.DrawLine(lightPen, 0, 0, 100, 100)
        bit2 = PictureBox1.Image
        PictureBox1.BackColor = Color.White
        'PictureBox1.BackColor = Color.Blue
g.DrawLine(lightPen, 0, 0, 100, 100)で描いた線分が消えないことが
確認できると思います。

編集 削除
ねろ  2005-06-25 19:03:10  No: 123065  IP: [192.*.*.*]

あれ!かんじんなのを抜かしちゃった。
×bit1 = PictureBox1.Image
○bit1 = CType(PictureBox1.Image, Bitmap)

編集 削除
マグ  2005-06-25 19:26:32  No: 123066  IP: [192.*.*.*]

描いた線が消えないのはBackColorで描画しているからです。
PictureBox1.BackColor = Color.White

g.Clear(Color.White)
に変えてみてください。
線も消えますよ。

>PictureBox1にどこでビットマップを読み込んでますか?
>ブレークポイントでブレークして、bit1とbit2の値を見れば
>ビットマップが読み込まれていないのが判りますが。

ビットマップは読み込んでいません。

解決はしたことにはなっていないのですが、
一回、bmpファイルを作ってからBitmap変数に入れることにしました。
bmpファイルを作らずにBitmap変数に渡しかった理由は
ソースを作るのが面倒だったのと、ハードディスクの空き容量を
抑えたかったのですが、無理なようなので、bmpファイルを作ってからに
することにしました。

魔界の仮面弁士さん、ねろさん、夏の朝も天玉うどんさん  ありがとうございます。

分からないことがありましたら、また、質問します。
そのときはよろしくお願いします。

編集 削除
ねろ  2005-06-25 20:35:32  No: 123067  IP: [192.*.*.*]

>解決はしたことにはなっていないのですが、
解決はしてませんよね。

>ビットマップは読み込んでいません。
ファイルから読み込んでいるって言ってるんじゃ有りません。
Step実行してみましたか?
bit1 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
を実行した後、「bit1」が「Nothing」となってるでしょ。
これは何を意味してるかわかりますか?
PictureBox1.BackColor = Color.Red
この結果「bit1」に何が入ると期待してましたか?

>無理なようなので、bmpファイルを作ってからに
bit1 = CType(PictureBox1.Image, Bitmap)
PictureBox1.Image = Nothing
PictureBox1.Image = bit1
これでbit1にPictureBox1のイメージが読み込まれる(セットされる)
サンプル書いたつもりですが。

編集 削除
夏の朝も天玉うどん  2005-06-26 08:57:31  No: 123068  IP: [192.*.*.*]

サンプルが悪かったようです。以下のソースで試してください。
赤色の背景に明るい色で線を引いています。その後Bit1に
取り込んでいます。背景を青色にし、取り込んだBit1を        
PictureBox1.Image に再設定します。すると期待の赤色の背景に
明るい線ではなく、青い背景に明るい線で表示されます。

        Dim lightPen As New Pen(Color.LightGray, 1)
        Dim bit1 As Bitmap, bit2 As Bitmap
        bit1 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        bit2 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        PictureBox1.Image = bit1
        Dim g = Graphics.FromImage(PictureBox1.Image)
        PictureBox1.BackColor = Color.Red
        g.DrawLine(lightPen, 0, 0, 100, 100)
        bit1 = PictureBox1.Image
        PictureBox1.BackColor = Color.Blue
        PictureBox1.Image = bit1
マグ様の先のコードでは
PictureBox1.BackColor = Color.Red  途中略
bit2 = CType(PictureBox1.Image, Bitmap)
赤色が入りそうな気がするでしょうが、bit2には何も入りません。

g.Clear(Color.White)これは当然Imageに描画しているので線が消えます。

赤の背景にしたければ
        Dim drawBrush As New SolidBrush(Color.Red)

        g.FillRectangle(drawBrush,0,0,PictureBox1.Width, PictureBox1.Height)
で塗りつぶしてください。

編集 削除
マグ  2005-06-26 11:13:47  No: 123069  IP: [192.*.*.*]

魔界の仮面弁士さん、ねろさん、夏の朝も天玉うどんさん  ありがとうございます。
解決できました。

いろいろと試していたら、BackColorとBitmapは違うものということが分かり、
勉強になりました。本当に感謝です。
実験したソースは下に記載しておきます。
色々、試して過ぎて、めちゃくちゃになっていますが・・・・・
今度は、彩度を下げたりとかのソースを作ってみます。
RGB色とHSB色の相互変換のソースは完成していますし・・・・・

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim bit1 As Bitmap
        bit1 = New Bitmap(PictureBox1.Width, PictureBox1.Height)
        bit1 = CType(PictureBox1.Image, Bitmap)
        PictureBox1.Image = Nothing
        PictureBox1.Image = bit1
        '試しに■を描画
        Dim g As Graphics = Nothing
        Dim brush As Brush = Nothing
        g = Graphics.FromImage(PictureBox1.Image)
        brush = New SolidBrush(Color.Black)
        g.FillRectangle(brush, 5, 5, 5, 5)
        If Not g Is Nothing Then
            g.Dispose()
            g = Nothing
        End If
        If Not Brush Is Nothing Then
            Brush.Dispose()
            Brush = Nothing
        End If
        bit1 = CType(PictureBox1.Image, Bitmap)
        PictureBox1.Image = Nothing
        PictureBox1.Image = bit1

        'グレースケール化
        bit1 = CType(PictureBox1.Image, Bitmap)
        Dim bit2 As Bitmap
        Dim cls As Filter_Color : cls = New Filter_Color
        bit2 = cls.ConvertToGrayscale(bit1)
        PictureBox1.Image = Nothing
        PictureBox1.Image = bit2
    End Sub

Public Class Filter_Color

    '***************************************************************
    'グレースケール化
    '---------------------------------------------------------------
    '関数:ConvertToGrayscale
    '---------------------------------------------------------------
    '第1引数:カラーのBitmapを渡す
    '戻り値 :グレースケールをBitmapで返す
    '***************************************************************
    Public Function ConvertToGrayscale(ByVal source As Bitmap) As Bitmap

        Dim bm As New Bitmap(source.Width, source.Height)
        Dim RGBx As Integer, RGBy As Integer
        For RGBy = 0 To bm.Height - 1
            For RGBx = 0 To bm.Width - 1
                Dim c As Color = source.GetPixel(RGBx, RGBy)
                Dim Gray As Integer = CInt(c.R * 0.3 + c.G * 0.59 + c.B * 0.11)
                bm.SetPixel(RGBx, RGBy, Color.FromArgb(Gray, Gray, Gray))
            Next
        Next
        Return bm

    End Function

End Class

編集 削除