画像の切り取り への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 (削除されました)  ()
投稿日時
2010/8/5 19:17:24
(削除されました)
投稿者 るきお  (社会人)
投稿日時
2010/8/5 12:47:44
こんにちは。
試してみましたがエラーにならずにうまく動きます。
よく見たわけではないのですが、CreateGraphicsメソッドには気にしなければいけないタイミングがあって、CreateGraphicsメソッドで生成しておいたGraphicsクラスのインスタンスを後で使用しようとするとうまく行かないことがあります。(あいまいでごめんなさい)
なので、CreateGraphicsメソッドを使用する場合は、その直後に描画処理を行うようにするといいと思っているのですが、今回PictureBox1.Refreshが入ることでなにかが内部的に変わってしまっているのかなと想像しました。
一応、CreateGraphicsメソッドに頼らずに書くとこうなると思います。
元ネタ:http://social.msdn.microsoft.com/Forums/ja-JP/vbgeneralja/thread/91c41bc2-2a23-4b01-ac95-19760d141dd3
※よく検証してません。想定外のことをするとエラーになります。例:クリック。
試してみましたがエラーにならずにうまく動きます。
よく見たわけではないのですが、CreateGraphicsメソッドには気にしなければいけないタイミングがあって、CreateGraphicsメソッドで生成しておいたGraphicsクラスのインスタンスを後で使用しようとするとうまく行かないことがあります。(あいまいでごめんなさい)
なので、CreateGraphicsメソッドを使用する場合は、その直後に描画処理を行うようにするといいと思っているのですが、今回PictureBox1.Refreshが入ることでなにかが内部的に変わってしまっているのかなと想像しました。
一応、CreateGraphicsメソッドに頼らずに書くとこうなると思います。
元ネタ:http://social.msdn.microsoft.com/Forums/ja-JP/vbgeneralja/thread/91c41bc2-2a23-4b01-ac95-19760d141dd3
※よく検証してません。想定外のことをするとエラーになります。例:クリック。
Public Class Form1
Dim WithEvents Picturebox1 As New PictureBox
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Picturebox1.Dock = DockStyle.Fill
Me.Picturebox1.Image = New Bitmap("C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water lilies.jpg")
Me.Controls.Add(Picturebox1)
End Sub
Dim IsDragging As Boolean
Dim startPos As Point
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Picturebox1.MouseDown
startPos = e.Location
IsDragging = True
End Sub
Dim currentPos As Point
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Picturebox1.MouseMove
If IsDragging Then
currentPos = e.Location
Picturebox1.Invalidate()
End If
End Sub
Dim p As New Pen(Color.Black, 1)
Dim selectedRect As Rectangle
Private Sub Picturebox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Picturebox1.Paint
selectedRect = New Rectangle(startPos, currentPos - startPos)
p.DashStyle = Drawing2D.DashStyle.Dash
e.Graphics.DrawRectangle(p, selectedRect)
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Picturebox1.MouseUp
If Not IsDragging Then
Return
End If
IsDragging = False
Dim img As New Bitmap(selectedRect.Width, selectedRect.Height)
Using g As Graphics = Graphics.FromImage(img)
g.DrawImage(Me.Picturebox1.Image, New Rectangle(0, 0, img.Width, img.Height), selectedRect, GraphicsUnit.Pixel)
End Using
Dim f As New Form
f.BackgroundImage = img
f.BackgroundImageLayout = ImageLayout.None
f.ClientSize = img.Size
f.Show()
End Sub
End Class
投稿者 (削除されました)  ()
投稿日時
2010/8/5 12:46:27
(削除されました)
投稿者 Free  (社会人)
投稿日時
2010/8/5 08:47:26
便乗質問失礼します
>オブジェクト参照がオブジェクト インスタンスに設定されていません。
オブジェクト参照とは何でしょう?
>オブジェクト参照がオブジェクト インスタンスに設定されていません。
オブジェクト参照とは何でしょう?
投稿者 トモヤ  (高校生)
投稿日時
2010/8/4 22:41:43
VB2010でしましたけど出来ませんでした。
投稿者 ときお  (社会人)
投稿日時
2010/8/4 21:24:40
エラーはでないようですが、トモヤさんが考えたものとは違った動作をします
環境はVB2010です。
環境はVB2010です。
投稿者 トモヤ  (高校生)
投稿日時
2010/8/4 20:40:46
画像の切り取りについて質問します。
まずフォームにPictureBox1、PictureBox2、ボタン1を設置します。
ボタン1に開くと書きます。
ボタン1のコードに
こう書きます。
それでマウスのドラッグで範囲を選択し画像を取得してPictureBox2 に表示のコードを見つけてやってみたのですが出来ませんでした。
こう書いてビルドして開くを押して画像を開いたらエラーが出ます。
ここの部分です。
オブジェクト参照がオブジェクト インスタンスに設定されていません。
と出ます。どうすればいいでしょうか?
まずフォームにPictureBox1、PictureBox2、ボタン1を設置します。
ボタン1に開くと書きます。
ボタン1のコードに
Dim dlgOpen As New OpenFileDialog 'フィルターを設定する
dlgOpen.Filter = "ビットマップ(*.bmp)|*.bmp|" & _
"JPEG(*.jpg)|*.jpg|" & _
"GIF(*.gif)|*.gif|" & _
"PNG(*.png)|*.png"
If dlgOpen.ShowDialog() = Windows.Forms.DialogResult.OK Then
'PictureBoxにイメージを読み込む
PictureBox1.Image = Image.FromFile(dlgOpen.FileName)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End If
こう書きます。
それでマウスのドラッグで範囲を選択し画像を取得してPictureBox2 に表示のコードを見つけてやってみたのですが出来ませんでした。
Private sPos As MouseEventArgs 'マウスのドラッグの開始点
Private ePos As MouseEventArgs 'マウスのドラッグの終了点
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = MouseButtons.Left Then
'開始点の取得
sPos = e
ePos = e
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
'マウスのドラッグで線を引く
If e.Button = MouseButtons.Left Then
Dim g As Graphics = PictureBox1.CreateGraphics()
Dim BPen As New Pen(Color.Black, 1)
BPen.DashStyle = Drawing2D.DashStyle.Dash
'描いたの一旦消す(VB6.0の XorPen の代り) # ここがこのサンプルのミソ
PictureBox1.Refresh()
'消える描画でドラッグ中の四角形を描く
g.DrawRectangle(BPen, sPos.X, sPos.Y, ePos.X - sPos.X, ePos.Y - sPos.Y)
ePos = e 'マウスポインタの移動終了点を取得
g.Dispose()
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If e.Button = MouseButtons.Left Then
PictureBox1.Refresh() '最後の四角形を削除
Dim g As Graphics = PictureBox1.CreateGraphics()
Dim BPen As New Pen(Color.Black, 1)
BPen.DashStyle = Drawing2D.DashStyle.Dash
'範囲確定の四角形を描く
g.DrawRectangle(BPen, sPos.X, sPos.Y, ePos.X - sPos.X, ePos.Y - sPos.Y)
g.Dispose()
'-------------- 指定範囲の画像取得部分 -----------------
'四角形の範囲の画像を取得
Dim rect As New Rectangle(sPos.X, sPos.Y, ePos.X - sPos.X, ePos.Y - sPos.Y)
'選択範囲が異常の場合表示処理をしない
If (ePos.X - sPos.X) < 2 Or (ePos.Y - sPos.Y) < 2 Then
Exit Sub
End If
'PictureBox2 のサイズを切り取った画像のサイズに合せる
Dim g2 As Graphics
'コピー元の PictureBox を指定の事
Dim bmp As Bitmap = New Bitmap(PictureBox1.Image)
With PictureBox2
.Image = New Bitmap(ePos.X - sPos.X, ePos.Y - sPos.Y)
.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize
g2 = Graphics.FromImage(.Image)
End With
'取得した画像を PictureBox2 に表示
g2.DrawImage(bmp, 0, 0, rect, GraphicsUnit.Pixel)
bmp.Dispose()
g2.Dispose()
End If
End Sub
こう書いてビルドして開くを押して画像を開いたらエラーが出ます。
ここの部分です。
g.DrawRectangle(BPen, sPos.X, sPos.Y, ePos.X - sPos.X, ePos.Y - sPos.Y)
オブジェクト参照がオブジェクト インスタンスに設定されていません。
と出ます。どうすればいいでしょうか?
出来るようになりました!!