To read the article online, visit http://www.4GuysFromRolla.com/articles/081303-1.aspx

A Robust Image Gallery for ASP.NET

By Robert Van Dyk


Introduction


In a previous 4Guys article - True Image Resizing - author Scott Mitchell demonstrated how to build a simple image gallery that displayed thumbnailed images. Wanting to build a gallery to store digital images of my friends and family, I eagerly read Scott's article and tried out the associated live demo. While Scott's article demonstrates how to build a functional image gallery, I found it left a lot to be desired in usability, both from the end user's standpoint and the Web master's standpoint. This article examines how to build a robust image gallery that, in my opinion, is more usable and graphically appealing than Scott's solution.

An Overview of the Enhancements


Before we dive into the code for my improved image gallery, let's first discuss how my image gallery is an improvement over Scott's. First, in examining the live demo I quickly realized that Scott took very little time to make the image gallery visually appealing. (You can tell he works primarily with the backend side of Web sites!) Noting this, I improved the UI by adding a basic HTML <table> for the Image Gallery to be displayed within. I also implemented a paged system that limits each screen to displaying five entries, to prevent pages from becoming cluttered.

Next, I realized that people may want to categorize their pictures in a certain manner, and group them in categories. For example, in a gallery of digital pictures of my friends and family, I might want to create a separate category for each event from which I have pictures. My image gallery application provides categorization of images into folders so that people viewing the gallery have an easy way of finding images that are related to one-another instead of a free-for-all mess. Specifically, the image gallery will search through a specified folder, and all of that folder's subfolders. The pictures in each subfolder are considered to be related to one another, and are therefore in their own group. This filesystem-based approach makes it easy for the Web master to add new images to existing categories and to create new categories.

Finally, I choose to improve upon the Image Listing by having some basic file information that could be harvested from the file properties of each image and displayed on the page. My image gallery application not only displays the thumbnailed image, but also its filename, file size, and full-scale image dimensions.

At the end of the article you'll find a link to download the complete image gallery application. Feel free to alter the source code as you see fit. The remainder of this article explains the design decisions made when creating this application, and examines the application's source code.

Examining the HTML for the Image Gallery


There is really nothing too exciting about displaying information in an HTML <table>. My image gallery application uses a DataList to display the images. A screenshot of the image gallery can be seen below; beneath that is the HTML portion of the ASP.NET Web page for displaying the image gallery.

A screenshot of the image gallery.

<table cellspacing=4 cellpadding=0 border=1 width=100% bgcolor=ffffff>
  <tr>
    <td colspan=5>
        <asp:label id="top" runat="server" />
    </td>
  </tr>

  <tr>
    <td colspan=5>
      <asp:DataList runat="server" id="dlPictures"  RepeatColumns="5" 
             Font-Name="Verdana" Font-Size="8pt"
             CellSpacing="5" Item-BorderWidth="1" Item-BorderColor="#c0c0c0" 
             BorderStyle="None" ItemStyle-Width="125" 
             CellPadding="0" ItemStyle-HorizontalAlign="Center" 
             ItemStyle-VerticalAlign="Bottom" GridLines="Both"
             ItemStyle-BorderStyle="Solid">
        <ItemTemplate>
            <table cellspacing=0 cellpadding=0 border=0 width=100% 
                                        height=100% bgcolor=ffffff>
              <tr>
                <td align="center">
                  <br><%# Container.DataItem %>
                </td>
              </tr>
            </table>
        </ItemTemplate>
      </asp:DataList>
    </td>
  </tr>
  <tr> 
    <asp:label id="bottom" runat="server" />
  </tr>
</table>

You can make the HTML as complicated as you want, or stick with simplicity, as I have done. But notice that there are three Web controls at work here: the first two are Label Web controls - <asp:label id="top" runat="server" /> and <asp:label id="bottom" runat="server" /> - and they plug in the upper and lower sections of the table, respectively. The upper part of the table serves the purpose of telling the user what directory he is looking at, and generates links that let the user navigate back to the root directories at any time. The lower part of the table tells how many pages there are in the current directory and provides "Prev" and "Next" links if (and only if) appropriate. (I will be going over the top label in more detail at the end of this article; I will leave it to you to go through the code to ascertain how the bottom label works, as its contents are much easier to generate.)

In addition to these two Label Web controls, there is also a DataList to display the actual images in the image gallery. In the DataList, note the RepeatColumn="5" attribute. This generates five columns worth of images (assuming there are at least five images to display; if there are fewer images, there will only be columns for each image to display). In my example I restrict the image gallery to have only 5 images per page, but you could easily extend this to any number of entries.

Unfortunately, changing the code to display other than five images per page requires a bit more work than simply changing the RepeatColumns property in the DataList. Namely, you'll need to pick through the code and change the places where the code relies on the RepeatColumn specification.

Each image in the image gallery is displayed in its own mini-HTML <table>. The DataList's ItemTemplate contains a <%# Container.DataItem %> which emits the HTML for the linked image and its accompanying file description information. (If you are unfamiliar with the <%# Container.DataItem %> syntax, be sure to read: An Extensive Examination of the DataGrid: Part 5.

Enhancing the User Interface with JavaScript Beautification


The finishing touch to our plain HTML section is a bit of client-side JavaScript that will make browsing the gallery more fun. By adding the line:

onMouseOver="javascript:if (document.all) this.style.backgroundColor='#eeeeee'; this.style.filter = 'alpha(opacity=100)'"
onMouseOut="javascript:if (document.all) this.style.backgroundColor='#ffffff'; this.style.filter = 'alpha(opacity=70)';"

into the <td> tag that contains the <%# Container.DataItem %>, the images will be highlighted when a user moves his mouse into a image table element. There is really no ASP.NET value to learn from this, but I show it to you because I think it enhances the look and feel of the gallery for the person looking at it.

Building an Image Array


At this point we have the end-user HTML design down, and are now ready to examine the source code that powers the application. For starters - I already mentioned this but I will reiterate it here - the DataList's ItemTemplate simply emits a string of HTML necessary to display the image and its properties. So, in order to build our DataList, we need to build an array of strings. Each element in this string array will contain the HTML to emit in order to display the appropriate image.

To build this array, we must have a data source. In this case, the data will be obtained by calling the GetDirectories() and GetFiles() methods on the current directory we are creating a display for. (These two methods are static methods in the Directory class. For more information on these methods, refer to the technical documentation. PathVar is the value of the directory that has been selected. For both the GetDirectories() and GetFiles() method calls the first parameter is the directory to search; the second parameter is the search string to look for. * is Microsoft's standard wildcard search, so we can use *.jpg to search for all JPEG images. Take a look at the code segment below and at the explanation that follows.

Dim images As Array
    
Dim s as String, html as String
Dim dirs As String() = Directory.GetDirectories(PathVar, "*")
Dim files  As String() = Directory.GetFiles(PathVar, "*.jpg")
    
images = Array.CreateInstance(GetType(String), files.Length + dirs.Length)
If dirs.Length <> 0 AND files.Length <> 0
  dirs.CopyTo(images,0)
  files.CopyTo(images, dirs.length)
Else If files.Length <> 0
  files.CopyTo(images,0)
Else If dirs.Length <> 0
  dirs.CopyTo(images,0)
Else 
  Response.Write("No Content to Generate.  Make sure you have images " & _
                 "or sub-directories in the Source Directory")
End If

dirs and files are string arrays. Images is an array that will store the combined contents of both the dirs and files arrays. Following the creation of the images array, an If statement is used to copy over the dirs and files arrays, as appropriate, into the images array. The CopyTo() method for arrays follows the format: SourceArray.CopyTo(destArray, ArrayLocationToBeginCopying). In the event that nothing is returned, we print out an error message.

The next step is to iterate through the five images (or directories) that will be displayed on the current page. We need to use an If/Else structure to distinguish between a JPEG file and a subdirectory, since JPEG files and directories are treated differently. The following code illustrates iterating through the correct five records in the array, and adding the appropriate HTML to the pics array depending on if the file is a JPEG file or a subdirectory.

Dim index As Integer
For index = (page-1)*5 to (page*5)-1
  if index < images.length
      
    Dim s As String = images(index)
    if s.ToUpper().IndexOf(".JPG") >= 0
      pics.Add(AddImage(s, imgHeight, imgWidth, inSubpageSlash))
        
    Else
      pics.Add(AddDirectoryLink(s, inSubpageSlash))
    end if
  end if
Next

Note that the loop's lower-bound starts at (page - 1) * 5, which will have values that are multiples of 5, such as 0, 5, 10, 15, and so on. The upper-bound is computed by (page * 5) - 1, and will have values like 4, 9, 14, 19, and so on. Hence, when displaying, say, page 1, the elements 5 through 9 will be pulled from the array and displayed appropriately depending on their type (a JPEG file or a subdirectory).

The first command in the For loop is a conditional to check if index < images.Length. This check ensures that the looping variable stays within the bounds of the array. If we were to omit this check, we'd run into trouble if, for example, there were two pages but only eight images. In this scenario, when viewing the second page, it would try to loop up to the 9th array index, which would result in an exception.

Since s is instantiated as a string that represents the filename, we search to see if it contains the substring .jpg. Since the IndexOf() method is case-sensitive, we first do a .ToUpper() on the string and then compare it with capital letters. This is done so that regardless of the file's extension's casing, we will correctly identify if it is a JPEG. If the substring .jpg is not found, it returns -1. (Note: this code will fail if you have a directory whose name contains the substring .jpg.)

In Part 2 we'll see how to create the HTML in order to display the JPEGs and directories in the image array.

  • Read Part 2!

  • Article Information
    Article Title: ASP.NET.A Robust Image Gallery for ASP.NET
    Article Author: Robert Van Dyk
    Published Date: August 13, 2003
    Article URL: http://www.4GuysFromRolla.com/articles/081303-1.aspx


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers