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.
USE [TestDatabase]
GO
/****** Object: Table [dbo].[ImgTable] Script Date: 02/01/2013 13:45:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[ImgTable](
[Sno] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [varchar](500) NULL,
[ImageName] [varbinary](max) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
In the ImgTable I have three columns:
-
Sno that is the identity column
-
Name
-
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.
<body>
<form id="form1" runat="server">
<div>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Image Width="100px" Height="100px" ID="Image1" runat="server" ImageUrl="<%# Bind('name') %>"/>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
</body>
In the cs file on the page load event I use the following:
string constring = @"Data Source=******;Initial
Catalog=TestDatabase;Integrated Security=True;User ID=****** ";
SqlConnection cn = new SqlConnection(constring);
cn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.ImgTable", cn);
DataTable dt = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
List<ThumbNail> li = new List<ThumbNail>();
foreach(DataRow row in dt.Rows)
{
li.Add(new ThumbNail { thumb = (byte[])row["ImageName"], sno = row["sno"].ToString() });
row["name"] = "Handler.ashx?SrNo=" + row["sno"].ToString();
}
dt.AcceptChanges();
Session["file"] = li;
Repeater1.DataSource = dt;
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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Summary description for ThumbNail
/// </summary>
public class ThumbNail
{
public byte[] thumb { get; set; }
public string sno { get; set; }
public ThumbNail()
{
//
// TODO: Add constructor logic here
//
}
}
Before I proceed let me explain what:
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.:
<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.
string nam = context.Request.QueryString["SrNo"].ToString();
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:
byte[] a = null;
var byt= mylist.Where(item => item.sno == nam).Select(item => item.thumb);
var e = byt.GetEnumerator();
while (e.MoveNext())
{
a = (byte[])e.Current;
}
context.Response.OutputStream.Write(a, 0, a.Length);
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
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web.SessionState;
using System.Web;
using System.Collections.Generic;
using System.Linq;
public class Handler : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
byte[] a = null;
string nam = context.Request.QueryString["SrNo"].ToString();
List<ThumbNail> mylist = (List<ThumbNail>)HttpContext.Current.Session["file"];
var byt= mylist.Where(item => item.sno == nam).Select(item => item.thumb);
var e = byt.GetEnumerator();
while (e.MoveNext())
{
a = (byte[])e.Current;
}
context.Response.OutputStream.Write(a, 0, a.Length);
context.Response.Flush();
}
public bool IsReusable
{
get
{
return false;
}
}
}
Output