How to Create Thumbnails of Images Stored in Database

Beginners commonly ask how to create thumbnails of images stored in a database and show them in an aspx page. So I decided to build a sample application that uses a repeater control, a generic handler and one aspx page.

My database table name is ImgTable.

  1. USE [TestDatabase]  
  2. GO  
  3. /****** Object:  Table [dbo].[ImgTable]    Script Date: 02/01/2013 13:45:38 ******/  
  4. SET ANSI_NULLS ON  
  5. GO  
  6. SET QUOTED_IDENTIFIER ON  
  7. GO  
  8. SET ANSI_PADDING ON  
  9. GO  
  10. CREATE TABLE [dbo].[ImgTable](  
  11.       [Sno] [bigint] IDENTITY(1,1) NOT NULL,  
  12.       [Name] [varchar](500) NULL,  
  13.       [ImageName] [varbinary](maxNULL  
  14. ON [PRIMARY]  
  15. GO  
  16. SET ANSI_PADDING OFF  
  17. GO 

In the ImgTable I have three columns:

  1. Sno that is the identity column

  2. Name

  3. ImageName that is of type VarBinary(MAX) that will store the image

Let's start coding the front end.

In the aspx page I have one repeater control in which I have used one ASP image.
  1. <body>  
  2.     <form id="form1" runat="server">  
  3.     <div>  
  4.         <asp:Repeater ID="Repeater1" runat="server">  
  5.             <ItemTemplate>  
  6.                 <asp:Image Width="100px" Height="100px" ID="Image1" runat="server" ImageUrl="<%# Bind('name') %>"/>  
  7.             </ItemTemplate>  
  8.         </asp:Repeater>  
  9.     </div>  
  10.     </form>  
  11. </body> 

In the cs file on the page load event I use the following:

  1. string constring = @"Data Source=******;Initial  
  2. Catalog=TestDatabase;Integrated Security=True;User ID=****** ";  
  3. SqlConnection cn = new SqlConnection(constring);  
  4. cn.Open();  
  5. SqlCommand cmd = new SqlCommand("SELECT * FROM  dbo.ImgTable", cn);  
  6. DataTable dt = new DataTable();  
  7. SqlDataAdapter sda = new SqlDataAdapter(cmd);  
  8. sda.Fill(dt);  
  9. List<ThumbNail> li = new List<ThumbNail>();  
  10. foreach(DataRow row in dt.Rows)  
  11. {  
  12.     li.Add(new ThumbNail { thumb = (byte[])row["ImageName"], sno = row["sno"].ToString() });  
  13.     row["name"] = "Handler.ashx?SrNo=" + row["sno"].ToString();  
  14. }  
  15. dt.AcceptChanges();  
  16. Session["file"] = li;  
  17. Repeater1.DataSource = dt;  
  18. Repeater1.DataBind(); 

Don't be confused with List<Thumbnail>li =new List<Thumbnail>(), Thumbnail is my class in which there is two fields of the thumb (type byte array) and sno of type string. As you can see in the preceding code, I created a list of the class type and added sno and image fetched from the database into it and put the list into a session variable that I will later use on my handler.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. /// <summary>  
  6. /// Summary description for ThumbNail  
  7. /// </summary>  
  8. public class ThumbNail  
  9. {  
  10.     public byte[] thumb { getset; }  
  11.     public string sno { getset; }  
  12.     public ThumbNail()  
  13.     {  
  14.         //  
  15.         // TODO: Add constructor logic here  
  16.         //  
  17.     }  
  18. } 

Before I proceed let me explain what:

  1. row["name"] = "Handler.ashx?SrNo=" + row["sno"].ToString();
Is doing. Its is just preparing the URL of the image that will be further bound to the imageurl attribute of the image inside the repeater control.

e.g.:
  1. <asp:Image id="Image_1" ImageUrl="Handler.ashx?srno=1" />
Let's move on to the handler. In the handler I have fetched the list from the session and the query string from it and put them into the mylist and nam variables.

  1. string nam = context.Request.QueryString["SrNo"].ToString();  
  2. List<ThumbNail> mylist = (List<ThumbNail>)HttpContext.Current.Session["file"];   

Now here based on nam I will fetch an image from the list and assign it to a byte array and write it to the output stream:

  1. byte[] a = null;  
  2. var byt= mylist.Where(item => item.sno == nam).Select(item => item.thumb);  
  3. var e = byt.GetEnumerator();  
  4. while (e.MoveNext())  
  5. {  
  6.     a = (byte[])e.Current;  
  7. }  
  8. context.Response.OutputStream.Write(a, 0, a.Length);  
  9. context.Response.Flush();   

I have used a LINQ query and Lambda Expression to extract an image from the list but if you want to use another way then you can.

Handler

  1. <%@ WebHandler Language="C#" Class="Handler" %>  
  2. using System;  
  3. using System.Web.SessionState;  
  4. using System.Web;  
  5. using System.Collections.Generic;  
  6. using System.Linq;  
  7. public class Handler : IHttpHandler, IRequiresSessionState  
  8. {  
  9.     public void ProcessRequest(HttpContext context)  
  10.     {  
  11.         byte[] a = null;  
  12.         string nam = context.Request.QueryString["SrNo"].ToString();  
  13.         List<ThumbNail> mylist = (List<ThumbNail>)HttpContext.Current.Session["file"];  
  14.         var byt= mylist.Where(item => item.sno == nam).Select(item => item.thumb);  
  15.         var e = byt.GetEnumerator();  
  16.         while (e.MoveNext())  
  17.         {  
  18.             a = (byte[])e.Current;  
  19.         }  
  20.         context.Response.OutputStream.Write(a, 0, a.Length);  
  21.         context.Response.Flush();  
  22.     }  
  23.     public bool IsReusable  
  24.     {  
  25.         get  
  26.         {  
  27.             return false;  
  28.         }  
  29.     }  
  30. } 

Output

Output.jpg