- 題名: 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と言う風に再描画を強制しているのが原因だとは思いますが、これ以外にいい手が思いつきません。
どのようにしたらパフォーマンスがあがるでしょうか?(マウスの動作にたいしてきびきび線を書くように…)
【解決するために何をしたか】
どぼん!の画像関係のページを一通り全て見て工夫を凝らしてみましたが、これ以外に正常に動作するコードがかけませんでした。(後ろの画像が消えてしまうなどで)