My All-in-One ASP.NET Photo Gallery Page

To handle sharing photos on the web, I wanted something simple to install and easy to use. I wasn't happy with Yahoo's photo service because of how it resized my photos. Here's what I came up with. When I have a batch of photos I want to group together I create a folder and upload the photos into the folder using FTP. Then I add to the folder one file, "default.aspx" which contains only the following content. The important part is in red. It is a reference to my all-in-one-page photo gallery code.


<%@ Import Namespace="System.Collections" %>
<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.Drawing.Drawing2D" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Text" %>
<!-- #include file = "..\inc_gallery.aspx" -->

The contents of my all-in-one photo gallery page, "inc_gallery.aspx", are shown below. You can see what it does by visiting one of my photos folders, such as "2006". Probably the most interesting part about this page is the code to generate thumbnails on the fly and stream them out without ever saving them to disk.


<script language="C#" runat="server">
/*

By Corey Trager, 2006

*/

void Page_Load(object sender, System.EventArgs e)
{
	string path = Server.MapPath(".");

	string type = Request["type"];

	string columns_string = Request["columns"];
	int columns;

	if (columns_string == null)
	{
		columns = 3;
	}
	else
	{
		columns = Convert.ToInt32(columns_string);
	}

	string label_length_string = Request["lable_length"];
	int label_length;
	if (label_length_string == null)
	{
		label_length = 30;
	}
	else
	{
		label_length = Convert.ToInt32(label_length_string);
	}


	// produce the thumbnail page
	if (type == null)
	{

		// create the page of thumbnails
		DirectoryInfo dir = new DirectoryInfo(path);

		FileInfo[] files = dir.GetFiles();
		Response.Write ("<title>Thumbnails - " + dir.Name.Replace("_"," ") + "</title>");
		Response.Write ("<style>");
		Response.Write ("body {font-family: verdana;}");
		Response.Write ("td {font-size: 10pt;}");
		Response.Write (".heading {font-size: 12pt; font-weight: bold;}");
		Response.Write ("</style>");
		Response.Write ("<div class=heading>Photos from " + dir.Name.Replace("_"," ")
			+ "</div>");
		Response.Write ("<table border=0 cellpadding=5 cellspacing=0>");
		int cnt = 0;
		string file_and_numbers;

		foreach(FileInfo file in files)
		{
			string short_name = file.Name;
			if (short_name.Length > label_length)
			{
				short_name = short_name.Substring(0,label_length) + "...";
			}

			if(file.Name.EndsWith(".jpg"))
			{
				if (cnt % columns == 0)
				{
					Response.Write("<tr>");
				}
				cnt++;

				string pic_numbers = Convert.ToString(files.Length - 1) + "," + cnt;

				// the thumbnamil
				Response.Write("<td align=center><br>");
				Response.Write("<a target=_photo href=default.aspx?type=pic&pic="
					+ HttpUtility.UrlEncode(file.Name)
					+ "&pages=" + pic_numbers + ">");
				Response.Write("<img border=0 src=default.aspx?type=thumb&thumb="
					+ HttpUtility.UrlEncode(file.Name)
					+ ">");
				Response.Write("</a>");

				// the text label
				Response.Write("<br>");
				Response.Write("<a target=_photo href=default.aspx?type=pic&pic="
					+ HttpUtility.UrlEncode(file.Name)
					+ "&pages=" + pic_numbers + ">");
				Response.Write(short_name);
				Response.Write("</a>");

			}
		}

		Response.Write ("</table>");

	}
	else if (type == "thumb")
	{

		string thumb = Request["thumb"];

		// Create a thumbnail
		Response.ContentType = "image/JPEG";
		System.Drawing.Image image = System.Drawing.Image.FromFile(path + "\\" + thumb);

		int width = image.Size.Width;
		int height = image.Size.Height;
		int new_width;
		int new_height;

		// preserve the aspect ratio
		if (width > height)
		{
			new_width = 80;
			new_height = new_width * height / width;
		}
		else
		{
			new_height = 80;
			new_width = new_height * width / height;
		}

		System.Drawing.Image thumbnail = new Bitmap(new_width, new_height, image.PixelFormat);
		Graphics graphics =  Graphics.FromImage(thumbnail);

		// this next line makes a big difference in quality
		graphics.InterpolationMode = InterpolationMode.HighQualityBicubic ;
		Rectangle rect = new Rectangle(0,0,new_width,new_height);
		graphics.DrawImage(image,rect);
		thumbnail.Save(Response.OutputStream,ImageFormat.Jpeg);

	}
	else if (type == "pic")
	{

		// display the picture itself

		string pic = Request["pic"];
		string pages = Request["pages"];

		if (pages != null)
		{
			Regex regex = new Regex(",");
			string[] parts = regex.Split(pages);

			int which = Convert.ToInt32(parts[1]);
			int max = Convert.ToInt32(parts[0]);

			if (which > 1)
			{
				Response.Write ("<a href=default.aspx?type=which&which=");
				Response.Write (Convert.ToString(which-1));
				Response.Write (">prev</a>   ");
			}

			Response.Write (parts[1] + " of " + parts[0]);

			if (which < max)
			{
				Response.Write ("   <a href=default.aspx?type=which&which=");
				Response.Write (Convert.ToString(which+1));
				Response.Write (">next</a>");
			}
		}

		Response.Write ("<p>" + pic);
		Response.Write ("<p><img src=");
		Response.Write (HttpUtility.UrlEncode(pic));
		Response.Write (">");

	}
	else if (type == "which")
	{

		// handle the "prev" or "next"
		int which = Convert.ToInt32(Request["which"]);


		DirectoryInfo dir = new DirectoryInfo(path);

		FileInfo[] files = dir.GetFiles();

		int cnt = 0;

		foreach(FileInfo file in files)
		{
			if(file.Name.EndsWith(".jpg"))
			{
				cnt++;
				if (cnt == which)
				{
					string pic_numbers = Convert.ToString(files.Length - 1)
						+ "," + cnt;
					Response.Redirect("default.aspx?type=pic&pic="
						+ HttpUtility.UrlEncode(file.Name)
						+ "&pages=" + pic_numbers);

				}
			}
		}

	}

}
</script>