Monday, August 25, 2008

Image Explorer

In this program we have used 4 controls viz: a TreeView Control, a ListView Control, a Panel, and a PictureBox. The TreeView Control is used to explore directories and files. The ListView control is used to display the list of all the �.bmp�, �.jpg�, and �.gif� files. The PictureBox is used to display the file selected in the ListView. The Panel is used to make the PictureBox scrollable.

We also plan to add a status bar with two panels in it to display the Path and Size of the selected file.

To start with, we have dragged the TreeView, ListView and the Panel into our form. Next we have dragged in the PictureBox. We have dragged the PictureBox into the panel and not in the Form. Here we should take care that our PictureBox should be larger in size than our Panel. This will make the whole thing scrollable. If the Picture is not big enough to fit in the Panel the Panel will automatically be provided with vertical and horizontal scroll bars. The PictureBox control is non-scrollable and it clips the regions of the picture, which do not fit in it.

We then have dragged in 3 GroupBoxes to enclose these three controls. We should make sure to right click on the GroupBox and select �Send to back�, to have the GroupBoxes in background.

Next we have dragged in a StatusBar in our Form. Next we clicked the StatusBar properties window, clicked on Panels (Collection) and added two panels by clicking the �Add� button with names: - myspanel1 and myspanel2 We then made the following changes in the properties window of the corresponding controls

Control Change To
TreeView Name tree
ListView Name list
Panel Name mypanel
Panel BorderStyle FixedSingle
PictureBox Name pic
1st GroupBox Name List
2nd GroupBox Name Files
3rd GroupBox Name Image
StatusBar Name Mysbar

Next we have added the following events to our program.

Control Event Meaning
TreeView AfterExpand Occurs when a node has been expanded
TreeView AfterSelect Occurs when selection has been changed
ListView SelectedIndexChanged Occurs when an selected index is changed

We have also manually added the following method:- getpath( ), adddrives( ), and check( ).We will look at these events and methods one by one.

We have first called the adddrives( ) method in the Form1 constructor after the InitializeComponent( ) call.

public Form1( )
{

InitializeComponent ( ) ;
adddrives ( ) ;

}

adddrives( ) function looks like this:

public void adddrives ( )
{

string [ ] drives = Directory.GetLogicalDrives ( ) ;
foreach ( string i in drives )
{

TreeNode t = new TreeNode ( ) ;
t = tree.Nodes.Add ( i ) ;
t.Nodes.Add ( " " ) ;

}

}

The static function GetLogicalDrives( ) retrieves the names of the logical drives on the machine in the form of strings. We have collected them in a string array called drives. We have added a node for every drive present in the machine. To do this we have created a new TreeNode every time and added it to the tree using the Nodes.Add( ) method. The last t.Nodes.Add( ) is used to display the �+� sign, and it adds a blank node .We should now add events to our program.

When we executed this program on our machine we got this

Lets look at the events we added for the TreeView control.

protected void tree_AfterExpand ( object sender, System.WinForms.TreeViewEventArgs e )
{

TreeNode t = e.node ;
DirectoryInfo d = null ;
if ( t.Parent == null )
{

t.Nodes.Remove( 0 ) ;
d = new DirectoryInfo ( e.node.Text ) ;
Check ( d, t ) ;

}

}

This event is fired when a node is expanded. We have collected the reference of the node to be expanded in t. Then we have created a directory referencing a null value. We have then checked if it�s a parent node or not. If it is, we have deleted the first blank node we had added using the Remove( ) method. We have stored the reference of this directory in d and have called the Check( ) method. The Check( ) method is shown below

public static void Check ( Directory d, TreeNode t )
{

FileSystemInfo [ ] f = d.GetFileSystemInfos ( ) ;
foreach ( FileSystemInfo i in f )
{

if ( i.GetType ( ).ToString ( ) == "System.IO.DirectoryInfo" )
{

DirectoryInfo d1 = new DirectoryInfo ( i.FullName ) ;
TreeNode t1 = t.Nodes.Add ( i.Name ) ;
Check ( d1, t1 ) ;

}


}

}

This is a recursive method. In this method we wish to explore all the directories and sub-directories. We have passed a directory object and a node to this function. We have collected them in d and t respectively. The GetFileSystemEntries( ) method returns all �Entries� in that particular directory, be it a file or a sub directory. We have used an array of the FileSystemEntry class to store them. We have then used a foreach loop to iterate through all the elements in the array. If the element happened to be a file, we neglected it. But if was a directory we added it as a node to the tree and called the Check( ) function on this directory to explore any sub directories, any sub-sub directories and so on within it. At the end of the function we have all the directories, sub-directories and so on, added to the tree.

If we select any of the directories in the TreeView we should get a list of .bmp, .jpg and .gif files, contained in that directory, in the ListView. For this the code added to the tree_AfterSelect( ) event handler is

protected void tree_AfterSelect ( object sender, System.WinForms.TreeViewEventArgs e )
{

selpath = getpath ( e.node ) ;
DirectoryInfo d = new DirectoryInfo ( selpath ) ;
FileInfo [ ] f = d.GetFiles ( ) ;
int n = 0 ;
list.Clear( ) ;
list.Invalidate( ) ;
foreach ( FileInfo i in f )
{

string str = i.Extension ;
if ( str == ".bmp" || str == ".jpg" || str == ".gif" )
{

list.Items.Add ( i.Name,n ) ;
n++ ;

}

}

}

We have added the string variable selpath as a private data member to the Form1 class, because we have to use it in the method list_ItemActivated( ) event. It stores the path. The getpath( ) method returns the full path of that particular node (selected directory) which we have collected in selpath. We will look at this method in a moment. After obtaining the complete path we have created a new directory object with this path. The call d.GetFiles( ) returns an array of all the files present in that particular directory. The Clear( ) and Invalidate( ) methods help in repainting and clearing the ListView. We have then used a foreach loop on all the files in the array. The .bmp, .jpg, and .gif files are filtered out and added to the ListView using the InsertItem( ) method. We have passed the index and Name of the file to this method. Let�s now look at the getpath( ) method

string getpath ( TreeNode h )
{

string result = h.Text ;
TreeNode hparent ;
while ( ( hparent = h.Parent ) != null )
{

string str = hparent.Text ;
if ( !str.EndsWith ( "\\" ) )
str += "\\" ;
result = str + result ;
h = hparent ;

}

return result ;

}

We have first stored the Text of the node (directory), which gives the name of the node in the string variable result. The logic here is, we have to create a path for the directory chosen. What we have in hand is only the name of the node and not the full path. We have to keep on prefixing the name with its parent�s name until we don�t get the topmost node, which will obviously be the drive name and then finally we will get the full path. We have collected the parent�s name in variable str. To do this we have used a while loop until we reached the drive (highest node). The statement, result = str + result, keeps on prefixing the parent�s name to result. h = hparent keeps on iterating from a node to its parent. When we come across a directory we have added a �\� to str. So, eventually the path is stored in result and returned back to the calling function.

Now if we double click on any item present in the ListView we should get the image in the PictureBox. For this the following code should be added to the list_ItemActivate( ) method.

protected void list_ItemActivate (object sender, System.EventArgs e)
{

string str = list.FocusedItem.Text;

if ( !selpath.EndsWith("\\" ) )

selpath += "\\" ;

str = selpath + str ;
Image img = Image.FromFile ( str ) ;
FileInfo f = new FileInfo(str) ;
myspanel1.Text = "Path: " + f.FullName ;
myspanel2.Text = "Size in bytes: " + f.Length ;
pic.Width = img.Width ;
pic.Height = img.Height ;
pic.Image = img;

}

We have first completed the full path of the file chosen by concatenating selpath with the selected Item�s text (nothing but the file name). Next we have created an object of the Image class. The FromFile( ) method creates an image from the specified file. We have displayed the File Path and Size of the selected file on the StatusBar. To do so we have to set the Text properties of both the StatusBars to FullName and Length as shown in the following snippet.

myspanel1.Text = "Path: " + f.FullName ;
myspanel2.Text = "Size in bytes: " + f.Length ;

FullName and Length are properties of the FileInfo class. The only thing left is to display the image in the PictureBox, which is accomplished by using the following statements.

pic.Width = img.Width ;
pic.Height = img.Height ;
pic.Image = img;

The Width and Height properties of the PictureBox are set to the Width and Height properties of the Image object. Last but not the least we have set the Image property of the PictureBox to our image object. This will display our image in the PicturBox. Following should be the output when we compile it:

No comments: