Display thumbnails for image files in a directory in C#

This example displays thumbnails for the images in a directory. It displays a tooltip when the mouse hovers over a picture and selects a picture if you click on it.

This program is actually much easier than you might think because controls do all of the work of arranging the pictures. The program contains a (green) FlowLayoutPanel with its AutoScroll property set to true. The program only needs to drop PictureBox controls onto it and it automatically arranges the PictureBoxes and displays scroll bars if necessary.

The following code shows how the program displays thumbnails when the directory in the TextBox changes.

// PictureBoxes we use to display thumbnails.
private List PictureBoxes = new List();

// Thumbnail sizes.
private const int ThumbWidth = 100;
private const int ThumbHeight = 100;

// The selected PictureBox.
private PictureBox SelectedPictureBox = null;

// Display thumbnails for the selected directory.
private void txtDirectory_TextChanged(object sender, EventArgs e)
{
    // Delete the old PictureBoxes.
    foreach (PictureBox pic in PictureBoxes)
    {
        pic.Click -= PictureBox_Click;
        pic.Dispose();
    }
    flpThumbnails.Controls.Clear();
    PictureBoxes = new List();
    SelectedPictureBox = null;

    // If the directory doesn't exist, do nothing else.
    if (!Directory.Exists(txtDirectory.Text)) return;

    // Get the names of the files in the directory.
    List filenames = new List();
    string[] patterns = { "*.png", "*.gif", "*.jpg", "*.bmp", "*.tif" };
    foreach (string pattern in patterns)
    {
        filenames.AddRange(Directory.GetFiles(txtDirectory.Text,
            pattern, SearchOption.TopDirectoryOnly));
    }
    filenames.Sort();

    // Load the files.
    foreach (string filename in filenames)
    {
        // Load the picture into a PictureBox.
        PictureBox pic = new PictureBox();

        pic.ClientSize = new Size(ThumbWidth, ThumbHeight);
        pic.Image = new Bitmap(filename);

        // If the image is too big, zoom.
        if ((pic.Image.Width > ThumbWidth) ||
            (pic.Image.Height > ThumbHeight))
        {
            pic.SizeMode = PictureBoxSizeMode.Zoom;
        }
        else
        {
            pic.SizeMode = PictureBoxSizeMode.CenterImage;
        }

        // Add the Click event handler.
        pic.Click += PictureBox_Click;

        // Add a tooltip.
        FileInfo file_info = new FileInfo(filename);
        tipPicture.SetToolTip(pic, file_info.Name + 
            "\nCreated: " + file_info.CreationTime.ToShortDateString() +
            "\n(" + pic.Image.Width + " x " + pic.Image.Height + ") " +
            ToFileSizeApi(file_info.Length));
        pic.Tag = file_info;
        
        // Add the PictureBox to the FlowLayoutPanel.
        pic.Parent = flpThumbnails;
    }
}

This code defines the List of PictureBoxes that it uses to store the images that it creates. It also defines constants ThumbWidth and ThumbHeight, which determine how big the thumbnails are. Finally it declares the SelectedPictureBox variable to track the currently selected PictureBox.

The txtDirectory_TextChanged does most of the work. First it removes the Click event handlers from any existing PictureBoxes and disposes of them. It removes all of the child controls from the flpThumbnails FlowLayoutPanel, resets the PictureBoxes List, and sets SelectedPictureBox to null.

Next the code uses Directory.Exists to see if the directory entered in the TextBox exists and returns if it doesn't. This happens, for example, if you are typing in the TextBox and haven't finished entering the directory's name.

The code then loops over an array of file patterns looking for png, gif, jpg, and other image file formats. For each format, the code uses the Directory.GetFiles method to find files matching the pattern. That method returns an array of file names. The code uses the filenames array's AddRange method to add all of the files it found to the filenames array. After finding the files that match all of the patterns, the program sorts the filenames array.

Now the program loops through the file names. For each file, it creates a PictureBox, sets its size to the right thumbnail size, and loads the file into the PictureBox's Image property.

Next if the image is larger than the PictureBox, the program sets the PictureBox's SizeMode to Zoom so it displays it as large as possible without distorting it. If the image is smaller than the PictureBox, the program sets SizeMode to CenterImage so it displays the image at full scale centered in the control.

The code sets the PictureBox_Click event handler (shown shortly) to catch the control's Click event and adds a tooltip describing the image. Finally the code sets the PictureBox's Parent property to the FlowLayoutPanel (so the PictureBox is displayed inside the FlowLayoutPanel).

The following code shows the PictureBox_Click event handler that executes when you click on a PictureBox.

// Select the clicked PictureBox.
private void PictureBox_Click(object sender, EventArgs e)
{
    PictureBox pic = sender as PictureBox;
    if (SelectedPictureBox == pic) return;

    // Deselect the previous PictureBox.
    if (SelectedPictureBox != null) SelectedPictureBox.BorderStyle = BorderStyle.None;

    // Select the clicked PictureBox.
    SelectedPictureBox = pic;
    SelectedPictureBox.BorderStyle = BorderStyle.Fixed3D;
}

The code converts the sender from a generic object into a PictureBox. If this is the same as the currently selected PictureBox, the event handler exits.

If there is a currently selected PictureBox, the code resets its BorderStyle to None. The code then sets SelectedPictureBox to the clicked control and sets its border to Fixed3D so you can tell it is selected. A real application might do something else with the image such as print it or display it at full scale in another window, or it might provide a separate button to let you print the currently selected image.

(Note that if you need to store more information about each image, such as the full file name, you could put it in its PictureBox's Tag property.)

Notice how the program makes controls do most of the graphical work. The FlowLayoutPanel automatically arranges the pictures and displays scroll bars if necessary so you don't have to. The PictureBoxes' ScaleMode properties size the images appropriately without distorting them. All the code really does is list the files and create the PictureBoxes.

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.