PictureBox に関しては今まで何回か登場していますねぃ。
今回は、ドラッグ&ドロップで画像の読み込み・お絵かき・お絵かき結果も含む画像の保存・画面キャプチャ・クリップボード出し入れ
と、ちょっと遊んでみました。
クリップボードの出し入れ、めっちゃくちゃ簡単で拍子抜けしました。
非同期読み込みなど面白そうで手をつけていないのもあるんですが、
敬愛する中さんの写真に自分のプログラムでどうしても「LOVE」と描きたくて頑張ってたら疲れてしまいました。
PictureBox を使う時に悩む理由って、多分 DOBON! さんの書かれているコレに尽きると思います。
PictureBoxのImageプロパティに関するよくある勘違い
■参考文献
PictureBox クラス
PictureBoxのImageプロパティに関するよくある勘違い(DOBON!さん)
Visual Basic Script Constants
■実行画像
最近の中さんをひょうじしてみました!!
赤字でダイイング・メッセージのような雰囲気になってしまいましたが LOVE って書いてみました!!
上で書いたものを意味もなく TIFF ファイルに保存してみました!!
Public Class PictureBoxTest
Private m_picBox As PictureBox = Nothing
Private m_image As Image = Nothing
Private m_fileName As String = String.Empty
' お絵かき用
Private m_isDrawing As Boolean = False
Private m_x As Integer
Private m_y As Integer
Private Enum Action
画像を保存する
保存する形式の選択
Formのキャプチャを取る
クリップボードの画像を読み込む
クリップボードに画像を保存する
End Enum
Private Sub PictureBoxTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim context As ContextMenuStrip = New ContextMenuStrip
' 保存に関するコンテキストメニュー
Dim saveImageMenu As ToolStripMenuItem = New ToolStripMenuItem()
context.Items.Add(saveImageMenu)
Dim formatDropDown As ToolStripComboBox = New ToolStripComboBox()
Dim saveButton As ToolStripButton = New ToolStripButton()
With saveImageMenu
.Text = Action.画像を保存する.ToString()
.DropDown.Items.AddRange(New ToolStripItem() {formatDropDown, saveButton})
End With
With formatDropDown
.Name = Action.保存する形式の選択.ToString()
.DropDownStyle = ComboBoxStyle.DropDownList
.Items.AddRange(New String() {"bmp", "png", "gif", "jpeg", "tiff"})
.SelectedIndex = 0
End With
With saveButton
.Text = "保存"
AddHandler .Click, AddressOf SaveToFile
End With
context.Items.Add(New ToolStripSeparator())
' Formのキャプチャに関するコンテキストメニュー
Dim captureFormMenu As ToolStripMenuItem = New ToolStripMenuItem()
context.Items.Add(captureFormMenu)
With captureFormMenu
.Text = Action.Formのキャプチャを取る.ToString()
AddHandler .Click, AddressOf CaptureForm
End With
context.Items.Add(New ToolStripSeparator())
' ClipBoard 読み込みに関するコンテキストメニュー
Dim loadClipBoardImageMenu As ToolStripItem = New ToolStripMenuItem()
context.Items.Add(loadClipBoardImageMenu)
With loadClipBoardImageMenu
.Text = Action.クリップボードの画像を読み込む.ToString()
AddHandler .Click, AddressOf LoadFromClipBoard
End With
' ClipBoard 書き込みに関するコンテキストメニュー
Dim saveClipBoardImageMenu As ToolStripItem = New ToolStripMenuItem()
context.Items.Add(saveClipBoardImageMenu)
With saveClipBoardImageMenu
.Text = Action.クリップボードに画像を保存する.ToString()
AddHandler .Click, AddressOf SaveToClipBoard
End With
' PictureBox の設定
Me.m_picBox = New PictureBox()
Me.Controls.Add(Me.m_picBox)
With Me.m_picBox
.ContextMenuStrip = context
.SizeMode = PictureBoxSizeMode.Zoom
.Dock = DockStyle.Fill
.ErrorImage = My.Resources.black中さん ' 読み込みでエラーが発生した場合の画像
Me.m_image = New Bitmap(Me.m_picBox.ClientRectangle.Width, Me.m_picBox.ClientRectangle.Height)
' Paint
AddHandler .Paint, AddressOf PicBox_Paint
' お絵かき用
AddHandler .MouseDown, AddressOf PicBox_MouseDown
AddHandler .MouseMove, AddressOf PicBox_MouseMove
AddHandler .MouseUp, AddressOf PicBox_MouseUp
End With
' Drag Drop された時に画像を表示する
Me.AllowDrop = True
AddHandler Me.DragDrop, AddressOf Form_DragDrop
AddHandler Me.DragEnter, AddressOf Form_DragEnterOver
AddHandler Me.DragOver, AddressOf Form_DragEnterOver
End Sub
Private Sub PictureBoxTest_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If Not Me.m_image Is Nothing Then
Me.m_image.Dispose()
Me.m_image = Nothing
End If
End Sub
'' Drag Drop されたら画像を表示
Private Sub Form_DragEnterOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
If IsImageFileDrop(e) Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub Form_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
If Not IsImageFileDrop(e) Then Return
Dim filename As String = DirectCast(e.Data.GetData(DataFormats.FileDrop, False), String())(0)
Dim ext As String = System.IO.Path.GetExtension(filename).ToLower()
Me.m_fileName = filename.Replace(ext, "").Substring(0, filename.Length - ext.Length)
Me.m_image = Bitmap.FromFile(filename)
System.Diagnostics.Debug.WriteLine("file :" & filename)
Me.PrintRowFormat()
' PictureBox に描画する
Me.DrawPictureBox()
End Sub
Private Function IsImageFileDrop(ByVal e As System.Windows.Forms.DragEventArgs) As Boolean
If Not e.Data.GetDataPresent(DataFormats.FileDrop) Then Return False
Dim filename As String = DirectCast(e.Data.GetData(DataFormats.FileDrop, False), String())(0)
Dim ext As String = System.IO.Path.GetExtension(filename).ToLower()
If ext.Contains("bmp") OrElse ext.Contains("png") OrElse _
ext.Contains("gif") OrElse ext.Contains("jpeg") OrElse ext.Contains("tiff") Then
Return True
End If
Return False
End Function
'' 画像を表示
Private Sub PicBox_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
e.Graphics.DrawImage(Me.m_image, 0.0F, 0.0F, Me.m_image.Width, Me.m_image.Height)
Me.m_picBox.Invalidate()
End Sub
Private Sub DrawPictureBox()
' PictureBox に描画する
Using g As Graphics = Graphics.FromImage(Me.m_image)
g.DrawImage(Me.m_image, Me.m_picBox.ClientRectangle)
End Using
Me.m_picBox.Invalidate()
End Sub
' ホントにその拡張子のファイル?
Private Sub PrintRowFormat()
Const wiaFormatBMP As String = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatPNG As String = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatGIF As String = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatJPEG As String = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
Const wiaFormatTIFF As String = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"
Dim rowValue As String = Me.m_image.RawFormat.ToString().ToUpper()
Dim raw As System.Drawing.Imaging.ImageFormat = Nothing
If rowValue.Contains(wiaFormatBMP) Then raw = System.Drawing.Imaging.ImageFormat.Bmp
If rowValue.Contains(wiaFormatPNG) Then raw = System.Drawing.Imaging.ImageFormat.Png
If rowValue.Contains(wiaFormatGIF) Then raw = System.Drawing.Imaging.ImageFormat.Gif
If rowValue.Contains(wiaFormatJPEG) Then raw = System.Drawing.Imaging.ImageFormat.Jpeg
If rowValue.Contains(wiaFormatTIFF) Then raw = System.Drawing.Imaging.ImageFormat.Tiff
If Not raw Is Nothing Then System.Diagnostics.Debug.WriteLine("raw:" & raw.ToString())
End Sub
'' マウスでお絵かき
Private Sub PicBox_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If String.IsNullOrEmpty(Me.m_fileName) Then Return
Me.m_isDrawing = True ' お絵かき中
Me.m_x = e.X
Me.m_y = e.Y
End Sub
Private Sub PicBox_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Me.m_isDrawing = False ' お絵かきおわり
End Sub
Private Sub PicBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If Not Me.m_isDrawing Then Return
' 線をお絵かき
Using g As Graphics = Graphics.FromImage(Me.m_image)
g.DrawLine(Pens.Red, Me.m_x, Me.m_y, e.X, e.Y)
End Using
End Sub
'' ファイルに保存
Private Sub SaveToFile(ByVal sender As Object, ByVal e As EventArgs)
If String.IsNullOrEmpty(Me.m_fileName) Then Return
Dim dd As ToolStripDropDown = DirectCast(DirectCast(sender, ToolStripButton).Owner, ToolStripDropDown)
Dim combo As ToolStripComboBox = _
DirectCast(dd.Items(Action.保存する形式の選択.ToString()), ToolStripComboBox)
Dim ext As String = DirectCast(combo.SelectedItem, String).ToLower()
Dim imageFormat As System.Drawing.Imaging.ImageFormat = System.Drawing.Imaging.ImageFormat.Bmp
Select Case ext
Case "bmp" : imageFormat = System.Drawing.Imaging.ImageFormat.Bmp
Case "png" : imageFormat = System.Drawing.Imaging.ImageFormat.Png
Case "gif" : imageFormat = System.Drawing.Imaging.ImageFormat.Gif
Case "jpeg" : imageFormat = System.Drawing.Imaging.ImageFormat.Jpeg
Case "tiff" : imageFormat = System.Drawing.Imaging.ImageFormat.Tiff
End Select
Dim savePath As String = System.IO.Path.ChangeExtension(Me.m_fileName, ext)
Me.m_image.Save(savePath, imageFormat)
MessageBox.Show(savePath & " に " & Environment.NewLine & _
imageFormat.ToString() & " 形式で保存しました")
End Sub
'' 画面キャプチャをとってファイルに保存
Private Sub CaptureForm(ByVal sender As Object, ByVal e As EventArgs)
Const IMAGE_DIR As String = "D:\wankuma\blogtest"
Using img As Bitmap = New Bitmap(Me.Width, Me.Height)
Me.DrawToBitmap(img, New Rectangle(0, 0, Me.Width, Me.Height))
Dim saveFileName As String = _
System.IO.Path.Combine(IMAGE_DIR, _
System.IO.Path.ChangeExtension(DateTime.Now.ToString("yyyyMMddHHmmss"), "bmp"))
img.Save(saveFileName)
MessageBox.Show(saveFileName & " に保存しました")
End Using
End Sub
'' クリップボードの画像を表示
Private Sub LoadFromClipBoard(ByVal sender As Object, ByVal e As EventArgs)
If Not Clipboard.GetImage() Is Nothing Then
Me.m_image = Clipboard.GetImage()
Me.PrintRowFormat()
' PictureBox に描画する
Me.DrawPictureBox()
End If
End Sub
'' クリップボードに画像を保存
Private Sub SaveToClipBoard(ByVal sender As Object, ByVal e As EventArgs)
If String.IsNullOrEmpty(Me.m_fileName) Then Return
Clipboard.SetImage(Me.m_image)
End Sub
End Class