画像ビューワーの2回目です。今回は、メインフォームのパネルに表示するサムネール・クラスを作成します。
| コントロール(クラス) | 機能 | |
|---|---|---|
| ・ LB1 | (Label) | 縮小画像の表示 |
| ・ LL1 | (LinkLabel) | ファイル名の表示 |
| ・ TIP1 | (ToolTip) | 画像情報の表示用 |
| 関数 | 種類 | 機能 |
|---|---|---|
| ・ New | コンストラクタ(オーバーロード) | ファイル名とサムネールサイズから初期化 |
| ・ SetImage | ユーザー定義 | イメージやテキストを取得して配置 |
| ・ LL1_Click | イベント | 元画像を表示するサブフォームを起動 |
ImageTile.vb (フォームデザイナのコードは省略しています)
' 内部変数
Private m_path As String ' ファイル名
' コンストラクタ(パス名を指定)
Public Sub New(ByVal path As String, ByVal size As Integer)
MyBase.New()
InitializeComponent()
SetImage(path, size) ' 画像の取得
End Sub
' イメージの設定(引数 : ファイルパス、サムネールサイズ)
Public Sub SetImage(ByVal path As String, ByVal size As Integer)
m_path = path ' ファイルのパスを変数に格納
Dim fRate As Double ' 縮尺
Dim nWidth, nHeight As Integer ' 画像サイズ
Dim oImage As Image = Bitmap.FromFile(m_path) ' イメージリソース
' コントロールのサイズの設定
Me.Size = New Size(size, size + LL1.Height)
' 画像サイズの取得
With oImage
If .Width <= size AndAlso .Height <= size Then
' 画像が表示領域よりも小さい時
nWidth = .Width
nHeight = .Height
ElseIf .Width >= .Height Then
' 幅 >= 高さ の時
fRate = .Height / .Width
nWidth = size
nHeight = CInt(size * fRate)
Else
' 幅 < 高さ の時
fRate = .Width / .Height
nWidth = CInt(size * fRate)
nHeight = size
End If
End With
' サムネールの設定
Dim oThumbnail As Image _
= oImage.GetThumbnailImage(nWidth, nHeight, Nothing, IntPtr.Zero)
If Not IsNothing(LB1.Image) Then LB1.Image.Dispose()
LB1.Image = oThumbnail
' ファイル名の設定
LL1.Text = IO.Path.GetFileNameWithoutExtension(m_path)
' ツールチップの設定
Dim strTip As String = IO.Path.GetFileName(m_path) & vbCrLf _
& "W" & oImage.Width & "×H" & oImage.Height & vbCrLf _
& Format(FileLen(m_path), "#,#") & " バイト"
TIP1.SetToolTip(LB1, strTip)
' リソースの開放
oImage.Dispose()
End Sub
' リンクラベルのクリック
Private Sub LL1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles LL1.Click
If IO.File.Exists(m_path) Then
' 別フォームに元画像を表示
Dim oForm As New SubForm(m_path)
oForm.Show()
End If
End Sub
サムネールのサイズは、メインフォームのメニューで選択できるようにします。ここでは、大中小、三つのサイズを設定していますが、コード上では Enum列挙体で定義を行っています。MainForm.vb
' 内部変数/定数
Private m_size As Integer ' イメージのサイズ
' 列挙体 : イメージ一辺の長さ(単位:ピクセル)
Enum ImageSize As Integer
Large = 128 ' 大きいサイズ
Medium = 96 ' 普通サイズ
Small = 64 ' 小さいサイズ
End Enum
' イメージサイズの選択
Private Sub SetImageSize(ByVal size As ImageSize)
' 現在チェックの付いているサイズメニュー : Static で値を保持
Static CheckedItem As MenuItem = Nothing
' 現在チェック中のメニューのチェックをはずす
If Not IsNothing(CheckedItem) Then CheckedItem.Checked = False
' チェックを付けるメニューを格納
Select Case size
Case ImageSize.Large : CheckedItem = mnSizeL
Case ImageSize.Medium : CheckedItem = mnSizeM
Case ImageSize.Small : CheckedItem = mnSizeS
End Select
CheckedItem.Checked = True ' メニューにチェックを付ける
m_size = size ' サイズを変数に格納
End Sub
' 表示メニュー : サイズメニューのクリック
Private Sub mnSizeL_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles mnSizeL.Click
SetImageSize(ImageSize.Large) ' 大きいサイズ
End Sub
Private Sub mnSizeM_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles mnSizeM.Click
SetImageSize(ImageSize.Medium) ' 普通のサイズ
End Sub
Private Sub mnSizeS_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles mnSizeS.Click
SetImageSize(ImageSize.Small) ' 小さいサイズ
End Sub
@ ツリービューのダブルクリック (TV1_DoubleClick関数) で、フォルダが選択された後、
A フォルダ内の画像ファイルの配列を取得 (GetImageFiles関数) し、
B サムネールを取得してパネルに追加 (SetImageTiles関数)、
この時発生するパネルのレイアウトイベント (PN1_Layout関数) で、
C 列数を算出して、サムネールを配置する、
| 関数 | 種類 | 機能 |
|---|---|---|
| ・ SetImageTiles | ユーザー定義 | パネルにサムネールを一覧表示 |
| ・ GetImageFiles | ユーザー定義 | フォルダ内の画像ファイルの配列の取得 |
| ・ PN1_Layout | イベント | 列数の算出 / サムネールの再配置 |
MainForm.vb ' 内部変数/定数 Private m_col As Integer ' 列数 Private m_path As String ' 現在のパス名 Const nSpaceX As Integer = 8 ' イメージ同士の間隔(よこ) Const nSpaceY As Integer = 4 ' イメージ同士の間隔(たて)
' SetImageTiles : 画像の一覧表示 Private Sub SetImageTiles(ByVal folder As String) ' ファイルが存在しない時は処理を中止 If IO.Directory.Exists(folder) = False Then Exit Sub m_path = folder ' フォルダ名を変数に格納 ' パネル内のコントロールをクリア PN1.Controls.Clear() ' 画像ファイルの配列を取得 Dim aFiles As String() = GetImageFiles(folder) If IsNothing(aFiles) Then Exit Sub ' イメージ(サムネール)を取得してパネルに追加 Dim i As Integer For i = 0 To aFiles.Length - 1 Cursor.Current = Cursors.WaitCursor Dim oTile As New ImageTile(aFiles(i), m_size) PN1.Controls.Add(oTile) SBP2.Text = (i + 1).ToString & "/" & aFiles.Length & " 読込中" ' 読込状況の表示 Application.DoEvents() ' 待機中のイベントを処理 Next ' ステータスバーパネルに情報を表示 SBP1.Text = "[" & IO.Path.GetFullPath(folder) & "]" ' パス名 SBP2.Text = "画像数 : " & i.ToString ' 画像数 Cursor.Current = Cursors.Default End Sub
' GetImageFiles : イメージファイルの取得 Public Shared Function GetImageFiles(ByVal folder As String) As String() Dim aExt As String() = {".bmp", ".jpg", ".jpeg", ".gif", ".png", ".ico"} ' 拡張子の配列 Dim sFile As String ' ファイル名 Dim aFile As String() ' ファイルの配列 Dim n As Integer = -1 ' 配列のサイズ Dim i As Integer For Each sFile In IO.Directory.GetFiles(folder) For i = 0 To aExt.Length - 1 ' 画像の拡張子とファイル属性をチェックして配列に加える ' ここでは隠し属性 (Hidden) のファイルを除いています If StrComp(IO.Path.GetExtension(sFile), aExt(i), CompareMethod.Text) = 0 _ AndAlso (GetAttr(sFile) And FileAttribute.Hidden) <> FileAttribute.Hidden Then n += 1 ReDim Preserve aFile(n) aFile(n) = sFile End If Next Next ' ファイルの並び替え If Not IsNothing(aFile) Then Array.Sort(aFile) Return aFile End Function
' パネルのレイアウトイベント Private Sub PN1_Layout(ByVal sender As Object, ByVal e As LayoutEventArgs) _ Handles PN1.Layout ' 列数の算出 (小数点を切り捨てて Integer型にキャスト) m_col = CInt(Fix(PN1.ClientSize.Width / (m_size + nSpaceX))) If m_col < 1 Then m_col = 1 ' 1未満の時は1列に設定 ' コントロールの再配置 Dim i As Integer For i = 0 To PN1.Controls.Count - 1 ' 位置の設定 (現在のスクロール位置も考慮) With PN1.Controls(i) .Left = (i Mod m_col) * (.Width + nSpaceX) + PN1.AutoScrollPosition.X .Top = (i \ m_col) * (.Height + nSpaceY) + PN1.AutoScrollPosition.Y End With Next End Sub

' 表示メニュー : 「再読み込み」
Private Sub mnReload_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles mnReload.Click
SetImageTiles(m_path) ' 一覧画像の再表示
End Sub
' フォームのロード
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
GetDrives() ' ツリービューの表示
SetImageSize(ImageSize.Medium) ' サイズメニューの選択
End Sub