Click here to Skip to main content
15,891,976 members
Articles / Web Development / ASP.NET

An ASP.NET thumbnail solution

Rate me:
Please Sign up or sign in to vote.
4.61/5 (52 votes)
10 Dec 2002Ms-RL12 min read 587.9K   8.5K   266  
An article describing a set of ASP.NET tools for generation of thumbnails and thumbnail views.
<%@ Control Language="C#" ClassName="ThumbList" Debug="true"%>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Drawing" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="PhilipSoft.Thumbnails" %>
<script runat="server">

    // ----- Copyright Philipos Sakellaropoulos 2002 -------
       private String _path,_vpath="", _filter="";
       private int _width,_height,_pagesize;
       private bool _bSaveThumbnails,_bShowFilenames;
       ThumbGenerator _oGenerator;
       // ------- public properties of the control ----------
       public int Width { get {return _width;} set {_width=value; } }
       public int Height { get {return _height;} set {_height=value; } }
       public String VPath { get {return _vpath;}
        set { _vpath=value.TrimEnd('/'); }
       }
       public int Columns
        { get {return MyThumbList.RepeatColumns;}
          set {MyThumbList.RepeatColumns=value; } }
       public String HeaderTitle;
       public bool SaveThumbnails
         { get {return _bSaveThumbnails;} set {_bSaveThumbnails=value; } }
       public bool ShowFilenames
         { get {return _bShowFilenames;} set {_bShowFilenames=value; } }
       // filter example: *.gif;*.jpg
       public String Filter { get {return _filter;} set { _filter=value; } }
       // im bored of get and set, i 'll make the rest public !!
       public bool AllowStretch;
       public bool AllowPaging;
       public bool HideNavBar;
       public bool Sort;
       public bool Refresh;
       public int PageSize
         { get {return _pagesize;}
         set {_pagesize=Math.Abs(value); } }
       public int CurPage;
       // by default don't use COM object unless explicitly requested
       public bool UseCOMobj;
       // create bevel effect for thumbnails
       public bool Bevel;
       public Color ItemBackColor
         { get { return MyThumbList.ItemStyle.BackColor; } set { MyThumbList.ItemStyle.BackColor=value; } }
       // new properties
       public bool ShowComments;
       public bool AllowEdit;
       
    // ~~~~~~~~~~~~~ Standard functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~
       void Page_Load(Object Src, EventArgs e)
       {
        // get physical path of images
        _path = Server.MapPath(_vpath);
        
        // register client script to got to a next page
         StringBuilder scriptb = new StringBuilder();
         scriptb.Append("<script language=\"javascript\">\n");
         scriptb.Append("//<!--\n function GoToPage(vpath,n) { \n");
         scriptb.AppendFormat("document._ctl0.{0}.value=n; \n",hdnCurPage.ClientID);
         scriptb.Append(Page.GetPostBackEventReference(this));
         scriptb.Append("\n } \n//-->\n </");
         scriptb.Append("script>");
   
         if(!Page.IsClientScriptBlockRegistered("clientGotoPageScript"))
            Page.RegisterClientScriptBlock("clientGotoPageScript", scriptb.ToString());

         // if not in update, bind every time since parameters may have change
         if(MyThumbList.EditItemIndex < 0)
           BindThumbList();
       }
       
   // we are databound, now we know how many pages we have
    // and the current page so we can create the navigation bar
    void Item_DataBound(Object sender, DataListItemEventArgs e)
    {
      if(e.Item.ItemType == ListItemType.Footer) {
       Trace.Warn("DataBound event for footer");
       PlaceHolder plLinks = (PlaceHolder)e.Item.FindControl("plLinks");
       if(AllowPaging && !HideNavBar) CreateNavBar(plLinks);
       hdnPrevPath.Value = VPath;
      }
    }
       void ThumbList_EditCommand(Object sender, DataListCommandEventArgs e) 
      {
         MyThumbList.EditItemIndex = (int)e.Item.ItemIndex;
         BindThumbList();
      }

      void ThumbList_CancelCommand(Object sender, DataListCommandEventArgs e) 
      {
         MyThumbList.EditItemIndex = -1;
         BindThumbList();
      }

      void ThumbList_UpdateCommand(Object sender, DataListCommandEventArgs e) 
      {
         DataRowView drvTarget; 
         String sComment = (String)((TextBox)e.Item.FindControl("txtComment")).Text;
         String sFilename = ((TextBox)e.Item.FindControl("txtFilename")).Text; 
         
         DataSet dsComments = ReadCommentsFromXML();
     	 DataView dvCommentsFromXML = dsComments.Tables[0].DefaultView;
     	 dvCommentsFromXML.RowFilter =  "Filename='"+sFilename+"'";
     	 // find row for filename or create a new one if does not exist
     	 if (dvCommentsFromXML.Count > 0) { 
     	   drvTarget = dvCommentsFromXML[0];
     	   dvCommentsFromXML.RowFilter = "";
     	 }
     	 else {
     	   drvTarget = dvCommentsFromXML.AddNew();
     	   drvTarget[0] = sFilename;
     	 }
        drvTarget[1] = sComment;
        drvTarget.EndEdit();
   
        dsComments.WriteXml(_path +"\\ThumbComments.xml");
        
        MyThumbList.EditItemIndex = -1;
        BindThumbList();
      }
        
  // ~~~~~~~~~~~~~~ Custom Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~    
      public void BindThumbList()
      {
      String[] files; int i;
      ArrayList arFilesAll = new ArrayList();
      try {
      if(_filter.Length==0 || _filter=="*.*") {
        files = Directory.GetFiles(_path);
        arFilesAll.AddRange(files);
      }
      else { // separate different filters with ';'
        String[] filters = _filter.Split(';');
        for(i=0; i<filters.Length; i++) {
          files = Directory.GetFiles(_path,filters[i]);
          arFilesAll.AddRange(files);
        }
      }
      // create the datasource (list of files)
      for(i=0; i<arFilesAll.Count; i++)
        arFilesAll[i] = Path.GetFileName((String)arFilesAll[i]);
      MyThumbList.Attributes["TotalFiles"] = arFilesAll.Count.ToString();
      if(_bSaveThumbnails) {
        _oGenerator = new ThumbGenerator();
        String pathThumbs = _path+"\\thumbnails";
        Directory.CreateDirectory(pathThumbs);
        } // end if save thumbs
      } catch(Exception exDir) { arFilesAll = new ArrayList(); }
      // sort file-list if requested
      if(Sort)
        arFilesAll.Sort();
        
      // page thumblist if requested
      ArrayList arFilesToShow;
      if(!AllowPaging)
         arFilesToShow = arFilesAll;
      else { // create a data source with only the page files
       int totalPages = (int)Math.Ceiling((float)arFilesAll.Count/PageSize);
       if(totalPages==0) totalPages=1;
       MyThumbList.Attributes["TotalPages"] = totalPages.ToString();
       if(CurPage<1) {
         // we have not given a page from caller, get it from hidden field
         try {
          CurPage = int.Parse(hdnCurPage.Value); //Request.Form["__EVENTARGUMENT"]);
         } catch(Exception exParse) { CurPage=1; }
        }
       if(hdnPrevPath.Value!=VPath) // restart page numbering
         CurPage = 1;
       Trace.Warn("BindThumbList: Current page=" + CurPage.ToString());
       // make sure current page is in the [1,totalPages] range
       if(CurPage>totalPages) CurPage=totalPages;
       else if(CurPage<1) CurPage=1;
       // store curPage in attributes and in hidden field
       MyThumbList.Attributes["CurPage"] = CurPage.ToString();
       hdnCurPage.Value = CurPage.ToString();
       // put files of the page in the dsPageFiles array
       int startIndex = (CurPage-1)*PageSize;
       int endIndex = Math.Min(CurPage*PageSize,arFilesAll.Count);
       arFilesToShow = arFilesAll.GetRange(startIndex, endIndex-startIndex );
      } // end define page

 
       // create in-memory DataTable to be the data source
      DataTable dtThumbs = CreateCommentsTable();
      DataView dvCommentsFromXML = null;
      if(ShowComments || AllowEdit) {
        DataSet dsComments = ReadCommentsFromXML();
        dvCommentsFromXML = dsComments.Tables[0].DefaultView;
      }
      // add rows with filenames
      for(i=0; i<arFilesToShow.Count; i++) {
        // Response.Write(arFilesToShow[i]);
        DataRow dr = dtThumbs.NewRow();
        dr[0] = arFilesToShow[i];
	dtThumbs.Rows.Add(dr);
      } // next file
      // add existing comments
      if((ShowComments || AllowEdit) && dvCommentsFromXML!=null) {
	for(i = 0; i < dvCommentsFromXML.Count; i++) {
	  String sFilename=((String)dvCommentsFromXML[i][0]).Trim();
          DataRow[] foundRows = dtThumbs.Select("Filename = '"+sFilename+"'");
          if(foundRows.Length>0) 
            foundRows[0][1] = dvCommentsFromXML[i][1]; // copy comment
 	}
      }
 
      MyThumbList.DataSource = dtThumbs.DefaultView;
      MyThumbList.DataBind();
      } // end method
    
    
     private void CreateNavBar(PlaceHolder plLinks)
     {
      Trace.Warn("CreateNavBar()");
      CurPage = int.Parse(MyThumbList.Attributes["CurPage"]);
      int totalPages = int.Parse(MyThumbList.Attributes["TotalPages"]);
      if(totalPages == 1) return;
    
      //  --- i found a better solution with client script, see below
      //  LinkButton lbtPrev = new LinkButton();
      //  lbtPrev.Text="<< Prev"; lbtPrev.CommandName="Prev";
      //  lbtPrev.Command += new CommandEventHandler(LinkButton_Command);
      //  plLinks.Controls.Add(lbtPrev);
    
      // put the path also into the page links to change link status
      // (visited or not) when we change the virtual path
      if(CurPage>1) {
      // GoToPage client script updates hidden field with target page
      // and then causes a postback
        plLinks.Controls.Add(new LiteralControl(String.Format(
          "<A href=\"javascript:GoToPage('{0}',{1});\">&lt;&lt; Prev</A>&nbsp;&nbsp;",
          VPath,CurPage-1 )));
      }
      for(int i=1; i<=totalPages; i++) {
        String si = i.ToString();
        plLinks.Controls.Add(new LiteralControl("&nbsp;"));
        if(i==CurPage) {
          Label lblPage = new Label();
          lblPage.Text = si; lblPage.Font.Bold = true;
          plLinks.Controls.Add(lblPage);
        }
        else {
        plLinks.Controls.Add(new LiteralControl(String.Format(
          "<A href=\"javascript:GoToPage('{0}',{1});\">{2}</A>",
          VPath,si,si)));
       }
       if(i%10==0)
         plLinks.Controls.Add(new LiteralControl("<br/>"));
      } // next i
      if(CurPage<totalPages) {
        plLinks.Controls.Add(new LiteralControl(String.Format(
          "&nbsp;&nbsp;<A href=\"javascript:GoToPage('{0}',{1});\">Next &gt;&gt;</A>",
          VPath,CurPage+1)));
      }
     }

  DataSet ReadCommentsFromXML() {
    DataSet dsComments = new DataSet("ThumbnailDataset");
    // read comments from XML file 
    try {
       dsComments.ReadXml(_path +"\\ThumbComments.xml");
    } catch(Exception exRead) { }
    if(dsComments.Tables.Count==0) 
      dsComments.Tables.Add(CreateCommentsTable());
    return dsComments;
   }

  DataTable CreateCommentsTable() {
   DataTable dtThumbs = new DataTable("ThumbComment");  
   DataColumn dcPrimary = new DataColumn("Filename", typeof(string));
   dtThumbs.Columns.Add(dcPrimary);
   dtThumbs.Columns.Add(new DataColumn("Comment", typeof(string)));
   dtThumbs.PrimaryKey = new DataColumn[] { dcPrimary };
   dtThumbs.CaseSensitive = false;
   return dtThumbs;
   }

    
     // test function - not used
     void LinkButton_Command(Object sender, CommandEventArgs e)
     {
       Trace.Warn("You chose: " + e.CommandName + " Item " + e.CommandArgument);
     }
    
       String NumImagesDisplayed() {
         String sNum=((ICollection)MyThumbList.DataSource).Count.ToString();
         if(AllowPaging) sNum+= " of " + MyThumbList.Attributes["TotalFiles"];
         sNum += " images";
         if(AllowPaging) {
           sNum += String.Format(" (Page {0} of {1})",
            MyThumbList.Attributes["CurPage"],
            MyThumbList.Attributes["TotalPages"]);
         }
         return sNum;
       }
    
       // construct url of thumbnail
       String ThumbUrl(String sFile)
       {
         // if we use saved thumbnails, we must check if the file exists
         // if not we must create it using the oGenerator object
         if(_bSaveThumbnails) {
           _oGenerator.SetParams(String.Format("{0}\\{1}",_path,sFile),
            _width,_height,AllowStretch,Bevel,UseCOMobj);
           String sNameToSave = _oGenerator.GetUniqueThumbName();
           String sPathThumbFile=String.Format("{0}\\thumbnails\\{1}",
               _path,sNameToSave);
           if(!File.Exists(sPathThumbFile)) {
               try {
                Bitmap bmThumb = _oGenerator.ExtractThumbnail();
               _oGenerator.SaveThumbnail(bmThumb,sPathThumbFile);
               } catch (Exception exSave) { }
           } // if not exists
          return String.Format("{0}/thumbnails/{1}",_vpath,sNameToSave);
         }
         else { // create thumbnail in memory using the HTTP handler
          StringBuilder thurl = new StringBuilder();
          thurl.AppendFormat("{0}/ThumbJpeg.ashx?VFilePath={1}/{2}",
            TemplateSourceDirectory,_vpath,sFile);
          if(_width>0)  thurl.AppendFormat("&Width={0}",_width);
          if(_height>0)  thurl.AppendFormat("&Height={0}",_height);
          if(AllowStretch) thurl.Append("&AllowStretch=true");
          if(Bevel) thurl.Append("&Bevel=true");
          if(UseCOMobj) thurl.Append("&UseCOMobj=true");
          if(Refresh) thurl.Append("&Refresh=true");
          return thurl.ToString();
        }
       }
       
       String AltString(String sFile)
       {
       	 FileInfo fi = new FileInfo(String.Format("{0}\\{1}",_path,sFile));
	 long FileSize = fi.Length;
         return "Name: " + sFile + "&#10;&#13;Size: " + FileSize/1024 + " Kb";
       }
       
</script>
<!-------------------- Controls content here ------------------------------------->
<ASP:DataList id="MyThumbList" RepeatDirection="Horizontal" RepeatColumns="4" CellSpacing="3" runat="server" EnableViewState="true" OnItemDataBound="Item_DataBound"
 OnEditCommand="ThumbList_EditCommand" OnUpdateCommand="ThumbList_UpdateCommand"
 OnCancelCommand="ThumbList_CancelCommand"
>
    <ItemStyle font-size="8pt" horizontalalign="Center" borderwidth="1px" borderstyle="Solid" backcolor="White"></ItemStyle>
    <FooterStyle font-size="8pt" horizontalalign="Center" backcolor="#FFFFC0"></FooterStyle>
    <HeaderStyle font-size="11pt" font-bold="True" horizontalalign="Center"></HeaderStyle>
    <SelectedItemStyle backcolor="#E0E0E0"></SelectedItemStyle>
    <EditItemStyle borderwidth="1px" borderstyle="Groove"></EditItemStyle>
    <ItemTemplate>
        <a href="<%# String.Format("{0}/{1}",_vpath,
         ((DataRowView)Container.DataItem)["Filename"]) %>" > 
        <img border="0" src="<%# ThumbUrl((String)((DataRowView)Container.DataItem)["Filename"]) %>"
        alt="<%# AltString((String)((DataRowView)Container.DataItem)["Filename"]) %>" /></a>
        <%# _bShowFilenames?"<br/>"+((DataRowView)Container.DataItem)["Filename"]:"" %>
        <%# ShowComments?"<br/>"+((DataRowView)Container.DataItem)["Comment"]:"" %>
        <br/><asp:LinkButton id="button1" Visible='<%# AllowEdit ? true:false %>' 
           Text="Edit" CommandName="Edit" runat="server"/>
    </ItemTemplate>

    <EditItemTemplate>
        <a href="<%# String.Format("{0}/{1}",_vpath,
         ((DataRowView)Container.DataItem)["Filename"]) %>" > 
        <img border="0" src="<%# ThumbUrl((String)((DataRowView)Container.DataItem)["Filename"]) %>"
        alt="<%# AltString((String)((DataRowView)Container.DataItem)["Filename"]) %>" /></a> 
        <%# _bShowFilenames?"<br/>"+((DataRowView)Container.DataItem)["Filename"]:"" %>
        <ASP:TextBox id="txtFilename" Visible='false' 
          Text='<%# ((DataRowView)Container.DataItem)["Filename"] %>' runat="server"/>
        <br/><ASP:TextBox id="txtComment" Multiline='true' size='30' Rows='4' TextMode="MultiLine"
           Text='<%# ((DataRowView)Container.DataItem)["Comment"] %>' runat="server"/>
        <br/><asp:LinkButton id="button2" Text="Save" CommandName="Update" runat="server"/>
        &nbsp;<asp:LinkButton id="button3" Text="Cancel" CommandName="Cancel" runat="server"/>
    </EditItemTemplate>

    <HeaderTemplate>
        <%# HeaderTitle %> 
    </HeaderTemplate>
    <FooterTemplate>
        <%# NumImagesDisplayed() %> 
        <tr style="font-size: 8pt;" align="center">
            <td colspan=<%# Columns %>
                > 
                <p >
                    <asp:PlaceHolder id="plLinks" runat="server"></asp:PlaceHolder>
                </p>
            </td>
        </tr>
    </FooterTemplate>
</ASP:DataList>
<input id="hdnCurPage" type="hidden" runat="server" />
<input id="hdnPrevPath" type="hidden" runat="server" />

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under Microsoft Reciprocal License


Written By
Web Developer Forthnet
Greece Greece
Software developer and Microsoft Trainer, Athens, Greece (MCT, MCSD.net, MCSE 2003, MCDBA 2000,MCTS, MCITP, MCIPD).

Comments and Discussions