イメージビューワー(1)

VB SampleImageViewer 1 : MainForm
 VB.net で画像ビューワーをつくってみたいと思います。画像用には GDI+ という便利なツールがあって、画像の表示や加工が簡単にできる機能を持っています。GIF や JPG など一般的な形式の画像のほとんどを、簡単に、しかも美しく表示できるのが何よりの利点です。ただし、処理が重いのが難点です。
 今回つくるのは下図のようなシンプルなもので、ツリービューで選択したフォルダから縮小した画像一覧を右側のパネルに並べて表示するというものです。さらに、画像下のファイル名部分をクリックすると、別フォームで元画像を表示するようにします。こちらでは画像の拡大縮小、回転などの機能を付加したいと思います。

 これより、3回(本編)をかけてアプリケーションの基本部分の完成を目指します。4回目以降は付加可能な機能のサンプルとなります。
【INDEX】
»Page1 [本編] プロジェクトの概観 / メインフォームの設計 / フォルダツリーの作成
Page 2 [本編] サムネールの設計 / サムネールの作成 / 画像サイズの設定 / 画像の一覧表示
Page 3 [本編] サブフォームの設計 / 元画像の表示 / 画像の拡大・縮小 / 画像の回転・反転
Page 4 [拡張編] 画像の保存 / 画像への枠入れ・文字入れ / 画像のトリミング
Page 5 [番外編] スライドショー / マニュアル・スライド / フィットモード / オート・スライド
(作成環境 : Visual Basic .net 2002 / Framework SDK 1.0)

●プロジェクトの概観

 本プロジェクトでは三つのクラスを作成します。EzuLite プロジェクトを作成し、あらかじめ以下の三つのファイルとクラスを追加しておきます。
 プロジェクトは、フォルダとサムネールを表示するメインフォーム (MainForm)、画像ファイルから元画像を縮小して表示するサムネールクラス (ImageTile)、サムネールをクリックすると元画像を表示するサブフォーム (SubForm) から成ります。(右図参照)
ファイル名クラス名(派生元)機能
MainForm.vbMainForm (Form)メインフォーム(フォルダと一覧画像の表示)
ImageTile.vbImageTile (UserControl)サムネール(一覧画像用のコントロール)
SubForm.vbSubForm (Form)サブフォーム(元画像表示用のフォーム)
 さらに、以下の二つの操作が必要です。
*プロジェクトのプロパティ で、スタートアップの設定を MainFormに変更する。
*参照設定に System.Management を加える。(ドライブ情報の取得に、ManagementObjectSearcher クラス と ManagementObject クラスを使用するため)
' MainForm.vb
Public Class MainForm
    Inherits System.Windows.Forms.Form
    ...
End Class

' ImageTile.vb Public Class ImageTile Inherits System.Windows.Forms.UserControl ... End Class
' SubForm.vb Public Class SubForm Inherits System.Windows.Forms.Form ... End Class
| ▲TOP |

●メインフォームの設計
 メインフォームとコントロールの配置は下図の通りとなります。
 変更したプロパティ値を挙げておきます。これ以外はほぼデフォルトのままですが、太字箇所の設定は必須です。なお、ドライブとフォルダのアイコンは VB のふろくのもので十分だと思います。
MainForm
... Menu : MN1
... Text : 絵図帖LITE
TV1
... ImageList : IL1
... ShowRootLines : False
... Dock : Left
PN1
... AutoScroll : True
... Dock : Fill
... BackColor : White
... BorderStyle : Fixed3D
SB1
... Size.Height : 24
... ShowPanels : True
... Panels : SBP1, SBP2
SBP1
... AutoSize : Spring
... Text : ""
SBP2
... AutoSize : None
... Width : 100
... Text : ""

MN1 : MenuItem
... mnFile : ファイル(&F)
... mnUpdate : 更新(&U)
... mnExit : 終了(&X)
... mnView ; 表示(&V)
... mnReload : 再読み込み(&R)
... mnSizeL : 大きいサイズ(&L)
... mnSizeM : 普通のサイズ(&M)
... mnSizeS : 小さいサイズ(&S)

IL1
... ImageSize : 16, 16
... ColorDepth : Depth24Bit

  (数字は ImageIndex の値)
| ▲TOP |

●フォルダツリーの作成
 今回作成するフォルダツリーは、「フォルダツリービュー(1)〜(3)」で作成したものの簡易版です。興味のある方はそちらも参考にしてください。ここでは、三つのユーザー定義関数と、二つのイベント関数をコーディングします。ツリービュー (TV1) で選択したフォルダ内の画像を、右側のパネル (PN1) に表示することになります。
関数名種類機 能
・ GetDrivesユーザー定義ルートノード(ドライブ)を取得してツリービューに追加
・ GetNodesユーザー定義子ノード(フォルダ)を取得してツリービューに追加
・ GetSubNodesユーザー定義孫ノード(サブフォルダ)を取得してツリービューに追加
・ TV1_BeforeExpandイベントノードを展開させる前にサブ(孫)ノードを追加しておく
・ TV1_DoubleClickイベントツリービュー(ノード)のダブルクリック時に画像を表示
*今回の方法では、ツリービューのツリーノードの FullPathプロパティと フォルダの FullPathプロパティは同じ値(文字列)となります。
*各フォルダ(ツリーノード)は、起動時にすべて追加するのではなく、ユーザー操作( "+/-" のクリックまたはノードのダブルクリック)に応じて追加 ( BeforeExpand イベント参照 ) します。すでに追加済みのフォルダ(ツリーノード)には、Tagプロパティに "1" を格納、未展開のツリーノードには "0" を格納して、二重にツリーノードが追加されないようにします。
*TV1_DoubleClick で呼び出している SetImageTiles 関数は、右側のパネルに画像を表示するための関数です。この内容は次回掲載します。
MainForm.vb (フォームデザイナのコードは省略しています)

' GetDrives : ドライブの取得
Private Sub GetDrives()
    ' ツリーノードのクリア
    TV1.Nodes.Clear()

    ' ドライブ一覧の取得
    Dim sSearch As String = "SELECT * From Win32_LogicalDisk"
    Dim oDisk As New Management.ManagementObjectSearcher(sSearch)
    Dim obj As Management.ManagementObject

    'ドライブを取得してノードを作成・追加
    For Each obj In oDisk.Get()
        Dim sType As String = obj("DriveType").ToString    ' ドライブタイプ
        Dim nImage As Integer        ' 該当する ImageList(IL1) の ImageIndex

        'イメージ(ドライブ用アイコン)の取得
        'DriveType...0=UnKnown,2=Removable,3=LocalDisk,4=Network,5=CD,6=RAM
        Select Case CInt(sType)
            Case 2 : nImage = 1
            Case 3 : nImage = 2
            Case 4 : nImage = 3
            Case 5 : nImage = 4
            Case Else : nImage = 5
        End Select

        'ルートノード(ドライブ部分)の作成
        Dim sName As String = obj("Name").ToString    ' ドライブ名
        Dim node As New TreeNode(sName, nImage, nImage)
        node.Tag = 0        ' 展開済みフラグ(0は未展開, 1は展開済み)
        TV1.Nodes.Add(node)

        'ルートノードに子ノードを追加
        If Not IsNothing(obj("Size")) Then
            GetNodes(node)
        End If
    Next
    oDisk.Dispose()    ' オブジェクトの破棄
End Sub

' GetNodes : 子ノードの取得 Private Sub GetNodes(ByVal node As TreeNode) Dim sPath As String = node.FullPath ' フォルダのパス名 Dim aDir As String() ' フォルダ名の配列 Dim sDir As String ' フォルダ名 If sPath.EndsWith("\") = False Then sPath &= "\" ' 末尾に\を付加 aDir = IO.Directory.GetDirectories(sPath) ' フォルダの配列の取得 Array.Sort(aDir) ' フォルダの並び替え ' 取得したフォルダからノードを作成・追加 For Each sDir In aDir If (GetAttr(sDir) And FileAttribute.Hidden) <> FileAttribute.Hidden Then ' 隠し属性のフォルダを除く Dim oNode As New TreeNode(IO.Path.GetFileName(sDir), 6, 7) oNode.Tag = 0 ' 展開済みフラグ(0は未展開を表す) node.Nodes.Add(oNode) End If Next End Sub
' GetSubNodes : サブ(孫)ノードの取得 Private Sub GetSubNodes(ByVal node As TreeNode) Dim oNode As TreeNode ' 指定ノード(node)の子ノード(node.nodes)にサブノードを追加 For Each oNode In node.Nodes GetNodes(oNode) Next node.Tag = 1 ' 展開済みフラグ(1は展開済みを表す) End Sub
' ツリービューの展開前処理 Private Sub TV1_BeforeExpand(ByVal sender As Object, _ ByVal e As TreeViewCancelEventArgs) Handles TV1.BeforeExpand ' 展開済みフラグ(Tagプロパティ)が 0 (未展開)ならサブノードを追加する If DirectCast(e.Node.Tag, Integer) = 0 Then Cursor.Current = Cursors.WaitCursor GetSubNodes(e.Node) Cursor.Current = Cursors.Default End If End Sub
' ツリービューのダブルクリック Private Sub TV1_DoubleClick(ByVal sender As Object, ByVal e As EventArgs) _ Handles TV1.DoubleClick ' フォルダ名の取得 Dim strPath As String = TV1.SelectedNode.FullPath ' 一覧画像の表示 SetImageTiles(strPath) End Sub

 ここまでのコーディングで、ロードイベントとファイルメニューを以下のように記述し、SetImageTile 関数の呼び出しをコメントアウトした上でフォームを立ち上げた時、下図のようにノードが展開できれば成功です。
' フォームのロード
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
    ' ツリービューの表示
    GetDrives()
End Sub

' ファイルメニュー 「更新」 Private Sub mnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles mnUpdate.Click ' ツリービューの更新 GetDrives() End Sub ' ファイルメニュー 「終了」 Private Sub mnExit_Click(ByVal sender As Object, ByVal e As EventArgs) Handles mnExit.Click ' アプリケーションの終了 Me.Close() Application.Exit() End Sub


| ■HOME | ◆プログラムTop | ▲ページの先頭 |