tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: うまくExtFloodFillが使用できません
投稿日: 2008/12/18(Thu) 23:53
投稿者よねKEN
> ExtFloodFill関数を用いて多角形の背景部分の色をとりあえず変えたいと思っています。
> その際にpictureboxからcreategraphicsで作られたgraphics型のハンドラを用いて実行すればちゃんとなるのですが、
> bitmap型からfromimageで作ったgraphics型のハンドラでは、うまくいきません。
>(その後picturebox.imageに代入したら、背景が変わっていませんでした)

私もいろいろ実験コードを書いてみましたが、うまくいきませんでした。
いろいろ検索してみた限りでは、ExtFloodFillを使うには、
Bitmapオブジェクトやhdcやブラシなど全般をWindowsAPIで何とかしないといけないっぽいです。

はっきりとしたところは私も解説できないのですが、
コード例で言うところの、g.DrawArcでの描画とExtFloodFillでの描画が
同一の画用紙上で作業して描かれていない感じなんですよね。

http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=3977&lngWId=10

↑上記のコードサンプルでは.NET Frameworkのクラスの処理とExtFloodFill関数との
橋渡しのために多くのWindowsAPIを駆使して処理しているようです。

http://www.codeproject.com/KB/GDI-plus/floodfillincsharp.aspx
↑こちらのコードはC#の例ですが、WindowsAPIを使わずに自前でExtFloodFill相当の処理を
実装しているようです。

> 後の作業で1pixelずつ背景を読み取って線を引こうと思っているのでどうしても背景のみを色を変えたbitmapの画像が欲しいのです。
> やはり一度pictureboxの内容をファイルに落としたりして読み込むほうが早いのでしょうか・・・。

たぶんExtFloodFillを使う案である限りは、WindowsAPIをたくさん駆使する方法しかないのではないでしょうか。
(CreateGraphicsで描いた描画内容をなんとかBitmapに取り込む方法があれば、
制限付き(画面が完全に見えている状態でないとNG)で、なんとかなるかもしれませんが。

> コード例:
> Dim img As New Bitmap(PictureBox1.Width, PictureBox1.Height)
> Dim g As Graphics = Graphics.FromImage(img)
> g.DrawArc(Pens.Black, 30, 30, 260, 200, 0, 360)
>
> Dim ret As Integer
> '丸の外側を塗りつぶす
> ret = ExtFloodFill(g.GetHdc, 0, 0, Color.Black.ToArgb, 0)
>
>     'ピクチャーボックスに入れる
> PictureBox1.Image = img
> MsgBox(ret)
>
> 'ハンドルを解放する
> g.ReleaseHdc()

コード例にあるような楕円だけに限って言えば、

Dim img As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
PictureBox1.Image = img

Dim g As Graphics = Graphics.FromImage(img)
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality

Dim rectF As New RectangleF(30.0F, 30.0F, 260.0F, 200.0F)

g.DrawArc(Pens.Black, rectF, 0, 360)

Dim path As New GraphicsPath()
Dim rectF2 As RectangleF = rectF

rectF2.Inflate(0.5F, 0.5F)

path.AddArc(rectF2, 0, 360)

Dim r As Region = New Region()
r.Exclude(path)
g.FillRegion(Brushes.Orange, r)


PictureBox1.Refresh()
r.Dispose()
g.Dispose()

というような方法で実現することもできますが、
ご質問の内容からするとこれではダメなんでしょうね。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。