- 題名: PictureBoxのパフォーマンスについて
- 日時: 2006/08/13 14:40:50
- ID: 17111
- この記事の返信元:
- (なし)
- この記事への返信:
- [17114] Re[1]: PictureBoxのパフォーマンスについて2006/08/13 18:13:23
- ツリーを表示
■No17111に返信(Wizardさんの記事) > まぁ仕方ないと言えば仕方ないのですが、VB6時代の似たコードでは特に問題ありませんでした。 > (PictureBox.Imageに画像を入れて、PictureBox.Drawで線を書かせていましたが、こんなに遅くなりません) VB6 に、PictureBox.Draw メソッドなんてありましたっけ…? > g.DrawImageと言う風に再描画を強制しているのが原因だとは思いますが、これ以外にいい手が思いつきません。 画像を BackgroundImage に割り当ててみては如何でしょう。 ''' for VB2005 Public Class Form1 Private BorderPen As New Pen(Color.Red, 2) Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load BorderPen.Alignment = Drawing2D.PenAlignment.Inset Me.WindowState = FormWindowState.Maximized Dim bmp As Bitmap = Bitmap.FromFile("c:\test.JPG") With PictureBox1 .Dock = DockStyle.Fill .BackgroundImageLayout = ImageLayout.None .BackgroundImage = bmp End With End Sub Private Sub Form1_FormClosing(ByVal sender As Object, _ ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing BorderPen.Dispose() End Sub Private Start As Point Private Rect As Rectangle Private IsMouseDown As Boolean = False Private Sub PictureBox1_MouseDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown IsMouseDown = True If e.Button = Windows.Forms.MouseButtons.Left Then Start = e.Location Rect = New Rectangle(Start, Drawing.Size.Empty) End If End Sub Private Sub PictureBox1_MouseMove(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove If IsMouseDown = True Then Dim P As Point = Start Dim S As Size = e.Location - Start If Start.X > e.X Then P.X = e.X S.Width = Start.X - e.X End If If Start.Y > e.Y Then P.Y = e.Y S.Height = Start.Y - e.Y End If Rect = New Rectangle(P, S) PictureBox1.Invalidate() End If End Sub Private Sub PictureBox1_MouseUp(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp IsMouseDown = False End Sub Private Sub PictureBox1_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint With e.ClipRectangle e.Graphics.DrawRectangle(BorderPen, 0, 0, .Width, .Height) End With e.Graphics.DrawRectangle(Pens.Red, Rect) End Sub End Class
分類:[.NET]
【解決したい問題】
WindowsアプリケーションをVB.netで作成しています。
画面いっぱいのウィンドウに画像を描画して、任意の選択範囲に切り取る作業を行うモジュールを作成している(正確にはVB6から移行している)のですが、選択する画面の作成で困っています。お力を貸してください。
FormにはPictureBoxが1つ貼ってあり、以下のコードがあります。
Public Class Form1
Dim TempPic As Bitmap
Dim PenSize As Integer = 2
'再描画関数
Public Function AutoGraphics(ByVal picSource As PictureBox) As Graphics
If picSource.Image Is Nothing Then
picSource.Image = New Bitmap(picSource.ClientRectangle.Width, picSource.ClientRectangle.Height)
End If
Return Graphics.FromImage(picSource.Image)
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TempPic = Bitmap.FromFile("C:\test.jpg")
'サイズ調整
Me.WindowState = FormWindowState.Maximized
With PictureBox1
.Dock = DockStyle.Fill
'枠と画像描画
Dim g As Graphics = AutoGraphics(PictureBox1)
Dim p As New Pen(Color.Red, PenSize)
g.DrawImage(TempPic, 0, 0)
g.DrawRectangle(p, 0, 0, .Width - PenSize + 1, .Height - PenSize + 1)
p.Dispose()
g.Dispose()
End With
End Sub
'選択範囲
Dim sx, sy As Integer '始点(x,y)
Dim IsMouseDown As Boolean = False
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
IsMouseDown = True
If e.Button = Windows.Forms.MouseButtons.Left Then
sx = e.X
sy = e.Y
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If IsMouseDown = True Then
Dim g As Graphics = AutoGraphics(PictureBox1)
Dim p As New Pen(Color.Red, PenSize)
g.DrawImage(TempPic, 0, 0)
g.DrawRectangle(p, 0, 0, PictureBox1.Width - PenSize + 1, PictureBox1.Height - PenSize + 1)
g.DrawLine(Pens.Red, sx, sy, sx, e.Y)
g.DrawLine(Pens.Red, sx, e.Y, e.X, e.Y)
g.DrawLine(Pens.Red, e.X, e.Y, e.X, sy)
g.DrawLine(Pens.Red, e.X, sy, sx, sy)
p.Dispose()
g.Dispose()
PictureBox1.Invalidate()
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
IsMouseDown = False
End Sub
End Class
この時、ドラッグすれば赤枠が表示され、範囲を選択できるのですが、全画面表示を行っているためパフォーマンスが悪く、CPU利用率が高くなり、マウスの動作にたいして赤枠の描画が遅れます。
まぁ仕方ないと言えば仕方ないのですが、VB6時代の似たコードでは特に問題ありませんでした。
(PictureBox.Imageに画像を入れて、PictureBox.Drawで線を書かせていましたが、こんなに遅くなりません)
g.DrawImageと言う風に再描画を強制しているのが原因だとは思いますが、これ以外にいい手が思いつきません。
どのようにしたらパフォーマンスがあがるでしょうか?(マウスの動作にたいしてきびきび線を書くように…)
【解決するために何をしたか】
どぼん!の画像関係のページを一通り全て見て工夫を凝らしてみましたが、これ以外に正常に動作するコードがかけませんでした。(後ろの画像が消えてしまうなどで)