Click here to Skip to main content
Click here to Skip to main content

Generic Image Handler Using IHttpHandler

, 13 Mar 2009 Public Domain
Rate this:
Please Sign up or sign in to vote.
Example of an HttpHandler to handle image URLs and hide server mapped paths from users. This can also be used to generate thumbnails of any size.

Introduction

Here, I want to share a nice way to display images on web pages using an HttpHandler. Using this method, we can hide an image's server mapped path from the user as in the image shown above. Also, the same image handler can be used to generate thumbnails of variable dimensions passed using the querystring.

Understanding the code

The heart of this generic image handler is the ImageHandler class which implements the IHttpHandler and IRequiresSessionState interfaces.

IRequiresSessionState specifies that the target HTTP handler requires read and write access to session-state values. This is a marker interface and has no methods.

The IHttpHandler interface's ProcessesRequest method is implemented in this handler where all the image processing logic goes. Every time the handler is invoked, the handler checks for parameters passed through the query string, generates the corresponding image response, and writes it to current context. For further requests of the same image, the response is saved in a hash table, in the session. The same image handler can be used for multiple groups of images. In this example, I have used it for two groups: User Images and Status Images. A Dictionary object map is used to map different image groups with the strict filename logic used here.

public void ProcessRequest(HttpContext context)
{
    if (context.Request["id"] != null  && 
        context.Request["tName"] != null)
    {
        Dictionary<string,> map = new Dictionary<string,>();
        map.Add("UserImage", "user");
        map.Add("StatusImage", "status");
        if (context.Request["xlen"] != null)
        {
            XLen = context.Request["xlen"].ToString();
        }
        if (context.Request["ylen"] != null)
        {
            YLen = context.Request["ylen"].ToString();
        }
        string id =  context.Request["id"].ToString();
        string tName = context.Request["tName"].ToString();
        Hashtable ht;
        if (context.Session[tName] != null)
        {
            ht = (Hashtable)context.Session[tName];
            if (!ht.ContainsKey(id))
            {
                FileStream fInfo = new FileStream(context.Server.MapPath("images/" + 
                                   map[tName].ToString() + id + ".jpg"), FileMode.Open);
                byte[] bFile ;
                bFile = GenerateThumbnail(fInfo, XLen, YLen);
                ht.Add(id, bFile);
                fInfo.Close();
            }
        }
        else
        {
            ht = new Hashtable();
            FileStream fInfo = new FileStream(context.Server.MapPath("images/" + 
                               map[tName].ToString() + id + ".jpg"), FileMode.Open);
            byte[] bFile ;
            bFile = GenerateThumbnail(fInfo, XLen, YLen);
            ht.Add(id, bFile);
            context.Session[tName] = ht;
            fInfo.Close();
        }
        Byte[] arrImg = (byte[])ht[id];
        context.Response.Clear();
        context.Response.ContentType = "image/jpeg";
        context.Response.BinaryWrite(arrImg);
        context.Response.End();
    }
}

A simple thumbnail generation routine is used to generate thumbnails of the desired size. It uses the System.Drawing.Image class' GetThumbnailImage() method to generate thumbnails.

private byte[] GenerateThumbnail(Stream fStream, string xLen, string yLen)
{
    Image img = Image.FromStream(fStream);
    Image thumbnailImage = img.GetThumbnailImage(int.Parse(xLen),int.Parse(yLen), 
          new Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero);
            
    MemoryStream imageStream = new MemoryStream();
    thumbnailImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);

    byte[] imageContent = new Byte[imageStream.Length];
    imageStream.Position = 0;
    imageStream.Read(imageContent, 0, (int)imageStream.Length);
    return imageContent;
}

Using the code

The web application is informed of the HttpHandler using the web.config.

<add type="ImageHandlerLib.ImageHandler, ImageHandlerLib" 
     path="ImageHandler.aspx" verb="*" />

The default thumbnail size has been set as 110X110 in the ImageHandler class. This dimension is used unless both the attributes are sent via the query string to the handler.

Displaying an image this way hides the server mapped path that we would normally use like "<img src="image/user1.jpg" />, which gives away our directory structure of the virtual directory. Instead, we use a generic URL and pass parameters requesting specific images in the query string. The general format for queering any image using the above handler is:

src = "ImageHandler.aspx?tName=[groupname]&id=[idnumber]"

Scope

To further make the image handler's URLs secure so that nobody else can directly access your URLs in their own applications, you can implement your own security checking code in the beginning of the ProcessRequest method.

Also, instead of the strict file naming logic (i.e., strict filename formats for image files) that I have used in this example, the code can be further customized to have file names of image files passed as query string parameters. That should make this image handler really generic. Smile | :)

History

  • Created: 12 March 2009.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

sunit_82
Software Developer (Senior) Geometric
India India
B.E. in Information Technology
MCTS(.NET 2.0 )

Comments and Discussions

 
QuestionDoesn't work on IIS7 Pinmemberrafaelverisys11-Apr-13 4:37 
AnswerRe: Doesn't work on IIS7 Pinmemberrafaelverisys11-Apr-13 5:01 
GeneralRe: Doesn't work on IIS7 Pinmembermmaurox27-May-13 4:50 
GeneralMy vote of 5 Pinmemberkhalleo7-Feb-13 5:01 
QuestionThis is very good article. PinmemberJayesh Sorathia27-Jan-13 21:59 
GeneralStoring images in Session is a terrible idea PinmemberFerretOfWrath25-Aug-09 6:58 
GeneralRe: Storing images in Session is a terrible idea PinmemberVikcia4-Jun-12 22:20 
Sometimes is a need to use dynamic images (for example, images from DB). In that case, I think nothing wrong to use session.
GeneralMy vote of 2 PinmemberGiga778-Apr-09 13:51 
GeneralGood One PinmemberMember 306113315-Mar-09 22:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 13 Mar 2009
Article Copyright 2009 by sunit_82
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid