Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# Photo Viewer with Windows Forms

0.00/5 (No votes)
16 Feb 2014 1  
This is an extension of Photo Viewer on MSDN

Introduction

This is a beginner tip to learn C# and ADO .NET. What you will learn from this post is listed below:

  1. How to use OpenFileDialog to select photos from local disk
  2. How to use saveFileDialog to save photos to local disk
  3. How to store and retrieve photos from SQL Server DB
  4. Use of Picture Box control

Few Words about the App

This app is an extension of the MSDN tutorial to make a photo viewer using C#. What I have added is the functionality to save and retrieve the images from SQL Server 2008 R2 database. The tip was developed using .NET framework 4.5.

Tools used to develop this app include Visual Studio 2013 and SQL Server 2008 R2.

It will work with lower versions of .NET framework as well.

The app has 4 picture boxes and buttons with the following functionality:

  • Add From File - Clicking on this button will open the file dialog and you can browse your local disk to display a picture of the empty picture box
  • Add To File - If you want to save a picture from app into local disk, you can click on this button. When you click on this button, a check box will appear corresponding to each picture. Check the check box corresponding to the picture you want to save and click on the button again. This opens the save dialog window and you can browse to your favorite location to save the picture.
  • Upload to Database - Click on the button to upload the picture to database. It works in a similar fashion as Add to File button. The only difference is that it saves it to SQL Server 2008 R2 database and not to local disk.
  • Download from Database - If you want to display an image from database on your app, use this button. Clicking on the button will populate a combobox for you with picture names. You can choose a picture and it will be displayed in one of the empty picture boxes.
The code for each button is explained below.

Using the Code

The first step is to initialize the main form. I have declared two generic lists, one of type "picturebox" and other of type "checkbox". The checkboxes will be used in 1:1 mapping with picture boxes. For example, the checkbox at index 0 will be mapped with picture box at index 0. Initialize the lists and add the controls to list. The purpose of adding them to the list is that they can be traversed easily when required.

 //Declare list to store picture box and checkbox controls
        List<PictureBox> listPB;
        List<CheckBox> chkBoxList;
        string str = string.Empty;
        public Form1()
        {
            InitializeComponent();
            listPB = new List<PictureBox>();
            chkBoxList = new List<CheckBox>();
            //Declare the connection string
            str= "Data Source=MYPC;Initial Catalog=myDB;Integrated Security=True";
            //Initialize the list
            listPB.Add(pictureBox1);
            listPB.Add(pictureBox2);
            listPB.Add(pictureBox3);
            listPB.Add(pictureBox4);
            chkBoxList.Add(chkpicture1);
            chkBoxList.Add(chkpicture2);
            chkBoxList.Add(chkpicture3);
            chkBoxList.Add(chkpicture4);

        } 

After initializing the file, let us write the code for the various functionality of the app.

  1. We will now see the code for the various buttons and try to understand how it works. We will start with Add from file button, as mentioned above. Clicking on the button will allow you to browse through your local disk and display the picture in picture box. We will be using a control here called OpenFileDialog control. This control opens up the file window to browse through the computer's local disk, To add this control to your app, open the toolbox and double click on OpenFileDialog control. Another thing to take care of is the size of the picture, how the picture will be displayed on the picture box depends on the size of the picture. To make sure that the full picture is visible before displaying the image, check if the picture size is more than the size of the picturebox, then set the PictureBoxSizeMode property to Zoom else it will be set as Normal. As mentioned previously, the picture will be displayed in an empty picture box, so a foreach loop has been added to traverse through the picturebox collection and check if the Image property of the picturebox is null, it indicates that the picturebox is empty and picture can be added there. Let us have a look at the important properties and methods used in the below code snippet.
    • openFileDialog1.ShowDialog() - Calling this method opens the window
    • pb.Load(openFileDialog1.FileName) - This loads the file chosen in the window to the picturebox
       private void btnAddFromFile_Click(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    //Loop through the picture boxes
                    foreach (PictureBox pb in listPB)
                    {
                        //Find an empty picture box
                        if (pb.Image == null)
                        {
                            //Load the image
                            pb.Load(openFileDialog1.FileName);
                            Image img = pb.Image;
                            //Adjust the image size after loading it to Picture box
                            if (pb.Width < img.Width && pb.Height < img.Height)
                            {
                                pb.SizeMode = PictureBoxSizeMode.Zoom;
                            }
                            else
                            {
                                pb.SizeMode = PictureBoxSizeMode.Normal;
                            }
                            break;
                        }
                    }
                }
            }
  2. As mentioned previously, to add pictures to file or to database when user clicks on the button, checkboxes will appear corresponding to pictureboxes that have images in them. The below mentioned code snippet loops through the picturebox collection and if the .Image property is not null will make the checkbox visible for the corresponding picturebox. As mentioned previously also the checkbox and picturebox collection have 1:1 mapping.
     public void ShowCheckBoxes()
            {
                int count = 0;
                //Loop through the picture box collection to find out the picture boxes that have images, only the checkboxes for those picture boxes will be visible
                foreach (PictureBox img in listPB)
                {
                    if (listPB[count].Image != null)
                    {
                        chkBoxList[count].Visible = true;
                    }
                    ++count;
                }
            } 

    To add pictures to the local disk, we will be using another control called saveToDialog. This control can be found in toolbox in Visual Studio under common controls. Here, adding a new SaveToDialog from toolbox will not be required as we are creating an object of the class at run time and utilizing its properties. Same can be done in case of OpenDialogBox. It is left to the programmer's discretion. Let us have a look at some important methods and properties used here.

    • save.Filter = "Bitmap files (*.bmp)|*.bmp|JPG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif"; - This piece of code restricts the file extension that can be used while saving the picture. '|' indicates the OR symbol.
    • save.FilterIndex = 3; - Filter property decides the index of the extension that will be visible by default in the save dialog. It starts from 1. In our case, the extension at index 3 is gif. So when user clicks the button 'gif' extension will be visible by default.
    • save.RestoreDirectory = true; - When the save window is open, then the current directory is changed to the save window, when you close the window, the original directory that was the current directory before save window opened should be restored. This line of code helps in achieving this.

       private void btnAddToFile_Click(object sender, EventArgs e)
            {
                ShowCheckBoxes();
                int count = 0;
                foreach (CheckBox chk in chkBoxList)
                {
                    if (chk.Checked)
                    {
                        int index = count;
                        SaveFileDialog save = new SaveFileDialog();
                        save.Filter = "Bitmap files (*.bmp)|*.bmp|JPG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif";
                        save.FilterIndex = 3;
                        save.RestoreDirectory = true;
    
                        if (save.ShowDialog() == DialogResult.OK)
                        {
                            listPB[count].Image.Save(save.FileName);
                        }
                    }
                }
            } 
  3.  The row in DB that holds the picture is a row of type varbinary hence the image must be converted into byte array before it is sent to DB. The below mentioned code snippet converts the image to byte array:
     image = System.IO.File.ReadAllBytes(imageLocation); 

    Here the image location refers to the location of the image on disk and is obtained by the below mentioned code snippet:

       string imageLocation = pictureBox1.ImageLocation; 


    The full code is shown below:

     private void btnUpload_Click(object sender, EventArgs e)
            {
                ShowCheckBoxes();
                int count = 0;
                //Loop through all the picture boxes and add pictures selected by users.
                foreach (CheckBox chk in chkBoxList)
                {
                    if (chk.Checked)
                    {
                        string imageLocation = pictureBox1.ImageLocation;
                        byte[] image = null;
                        //Convert the image into byte array for saving it to DB
                        image = System.IO.File.ReadAllBytes(imageLocation);
                        SqlConnection sqlCon = new SqlConnection(str);
                        System.Data.SqlClient.SqlCommand command = 
                        new System.Data.SqlClient.SqlCommand
                        ("insert  into test(photo,name) values (@photo,@name)", sqlCon);
                        command.Parameters.AddWithValue("@photo", image);
                        command.Parameters.AddWithValue("@name", imageLocation);
                        sqlCon.Open();
                        command.ExecuteNonQuery();
                        sqlCon.Close();
                    }
                    ++count;
                }
            } 
  4. To download and display pictures in picturebox, use the following code. The process will be done in two steps. In the first step, a combobox will be populated with picture names and once the user chooses the picture name from combobox the corresponding picture will be loaded in the picturebox. The code to load the picture is written in the selected index changed event of combobox:
      private void button4_Click(object sender, EventArgs e)
            {
                SqlConnection sqlCon = new SqlConnection(str);
                System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("select name from test", sqlCon);
                sqlCon.Open();
                SqlDataAdapter da = new SqlDataAdapter(command);
                DataTable dt = new DataTable();
                da.Fill(dt);
                sqlCon.Close();
                comboBox1.DataSource = dt;
                comboBox1.DisplayMember = "Name";
                comboBox1.ValueMember = "Name";
            } 

    This is the selected index changed event of combo box.

     private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                SqlConnection sqlCon = new SqlConnection(str);
                System.Data.SqlClient.SqlCommand command = 
                new System.Data.SqlClient.SqlCommand
                ("select photo from test where name=@name", sqlCon);
                command.Parameters.AddWithValue("@name", comboBox1.SelectedValue.ToString());
    
                sqlCon.Open();
                byte[] image = (byte[])command.ExecuteScalar();
                if (image != null)
                {
                    sqlCon.Close();
                    //Save the picture from Db in the memory stream
                    MemoryStream ms = new MemoryStream(image);
                    //Load the picture from memory stream to picture box
                    //pictureBox1.Image = Image.FromStream(ms);
                    foreach (PictureBox pb in listPB)
                    {
                        //Find an empty picture box
                        if (pb.Image == null)
                        {
                            pb.Image = Image.FromStream(ms);
                            break;
                        }
                    }
    
                }
            } 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here