• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:図の削除直後の再描画)

図の削除直後の再描画

このQ&Aのポイント
  • VB2008 Express Edditionを使って、写真画像に直線等の図形を重ねるプログラムを作っています。
  • 図形の削除と再描画を同じボタンに割り当てて行うと、一瞬図形が表示されてすぐに消えてしまいます。
  • 回避するためには、図形の削除と再描画を別々のボタンに割り当てて行う必要があります。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

#1 Wizard_Zeroです。 補足の件、検証してみました。 下記のように、PictureBoxを継承したクラスを作り、OnPaintBackgroundとOnPaintをそれぞれオーバーロードした上で、個々の動作を止めてその動作を検証。 Friend Class PictureBoxEx Inherits Windows.Forms.PictureBox Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs) ' 背景の描画を中止 'MyBase.OnPaintBackground(pevent) End Sub Protected Overrides Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs) ' Paintの呼び出しを中止 'MyBase.OnPaint(pe) End Sub End Class 結果はこうなりました。 結果1. OnPaintBackgroundとOnPaintの両方を止める 真っ黒で何も描画されない。 結果2. OnPaintだけを止め、OnPaintBackgroundを実行させる。 背景色+背景画像が描画される。 結果3. OnPaintBackgroundだけを止め、OnPaintを実行させる。 真っ黒な背景にImageへ描き込んだ画像が描画される。 以上のことから、PictureBoxの描画順序は・・・ 1. PictureBoxを黒で塗りつぶす(イベント不明) 2. OnPaintBackgroundで、背景色の塗りつぶしとBackgroundImageに設定した画像の描画が行われる 3. OnPaintで、Imageプロパティに描き込んだ画像が描画される。 となります。 2~3では黒く塗りつぶしているところがないので、ちらつきの原因があるとすれば、1~2に遷移するところだと思います。ただ、私のほうでは特にちらつきは発生しませんでした。 ちらつきの原因は他にあるかもしれません。 Imageを透明色でクリアする点ですが、透明色でクリアしないと背景画像がImageで上書きされてしまいます。「透明で消す」というと不思議な感じがしますが、要はImageを構成する画像のビットを全てTransparent(A:R:G:B = 0:0:0:0)で置き換えるということです。 ※黒の場合はA:R:G:B = 255:0:0:0 になります。 ちらつきの原因はImageを透過合成するときかもしれませんが、GDI+が内部でどのように処理しているのかも分からないのでなんとも言えませんねぇ…。

fatbowler
質問者

お礼

詳細な調査、ありがとうございました。 こちらでも色々試してみたのですが、ちらつきは再描画に関係なく Dim gp As Graphics = PictureBox1.CreateGraphics() gp.Clear(Color.Transparent) PictureBox1.Refresh() gp.Dispose() としただけで発生しました。 どうも gp.Clear(Color.Transparent) が、透過色ではなく真っ黒に塗り潰しているようです。 試しに gp.Clear(Color.Black) に書き換えても、見た目には全く変わりません。VBのバグ? 結局、 PictureBox1.Refresh() こそが(一時的に描いた)図形を消去していることが分かり、 図形の消去をこの1文だけにすることで、ちらつきもなくなりました。 本筋ではないかもしれませんが、とりあえずやりたいことは問題なく できるようになりました。 どうもありがとうございました。

その他の回答 (1)

回答No.1

CreateGraphicsを使った描画だと、PictureBoxが他のウィンドウに隠れた場合や、リサイズ時に再描画されずに消えてしまうのではないでしょうか?? また、PictureBoxのImageプロパティは、再描画時に自動的に描画されるImageオブジェクトを格納するものなので、画像を消去するためだけにDisposeしてしまうのもどうかと・・・。 回避策ではありませんが、VB2005で書いたコードを掲載しておきます。なお、PictureBox1には、あらかじめBackgroundImageが設定されているものとします。 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' PictureBoxと同じサイズのビットマップを生成しImageプロパティにセットしておく。 ' 透過合成するので、24bitRGBではなく32bitARGBで。 PictureBox1.Image = New Drawing.Bitmap(PictureBox1.Width, PictureBox1.Height, Drawing.Imaging.PixelFormat.Format32bppArgb) End Sub ' Button1のクリックで描画 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' ImageプロパティからGraphicsを生成 Using gp As Drawing.Graphics = Drawing.Graphics.FromImage(PictureBox1.Image) ' 直線を描画 gp.DrawLine(Drawing.Pens.Pink, 10, 10, 200, 40) End Using ' PictureBox1を更新 PictureBox1.Refresh() End Sub ' Button2のクリックで消去 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Using gp As Drawing.Graphics = Drawing.Graphics.FromImage(PictureBox1.Image) ' 透明色で消去。(白や黒だと背景が透過されなくなります) gp.Clear(Drawing.Color.Transparent) End Using PictureBox1.Refresh() End Sub

fatbowler
質問者

お礼

アドバイスありがとうございます。 VBは不慣れなもので、ご指摘、勉強になります。 ちなみに、CreateGraphicsを使った描画だと再描画されないことは 認識していましたが、まずは動くものを作ってみて、改良はその後と 考えていました。 質問に提示した図形消去の方法は、本やWEBで調べた結果、この方法と 「背景色で塗り潰す」という強引な方法しか得られなかったためです。 ご提示の「透明色で塗り潰す」のが目的に非常に近く、この方法に 入れ替えてみたら一応はうまく動作しました。 ただ、VBの仕様かもしれませんが、一旦黒で塗り潰して、Refresh()で 再描画しているようで、画面のちらつきが気になります。 ちらつきを止める方法と、Imageをクリアするのに「透過色で塗り潰す」 のが妥当な方法なのか、引き続きよろしくお願いします。

関連するQ&A