Sep 29 2006

Using thumbshots.org in ASP.NET and C# - part 2

Posted by admin under Controls

Please start reading this from the beginning

Part 2 - we continue our development of the thumbshots.org cache handler:

Our img src will point to: img src="thumbshot.ashx?u=www.yoursite.com"

and lets start with looking at the handler code:



    public void ProcessRequest (HttpContext context) 
    {
        System.Drawing.Image oImgOriginal;
        System.Drawing.Image oImgWrite;
        
        string sStoreLocation = context.Server.MapPath("./app_data/fetchimages/");
        int RefreshAfterDays = 30;

        string sU = context.Request["u"];
        if (sU == null || sU.Length == 0)
            sU = "http://www.aspcode.net";
        if (sU.ToLower().StartsWith("http") == false)
            sU = "http://" + sU;

        string sUrl = HttpUtility.UrlEncode(sU);
        
        string sPhysicalFile = System.IO.Path.Combine( sStoreLocation , sUrl + ".jpg" );

        bool fGetFile = false;
        if (!System.IO.File.Exists(sPhysicalFile))
            fGetFile = true;
        else
        {
            //Check date...
            System.IO.FileInfo oInfo = new System.IO.FileInfo(sPhysicalFile);
            TimeSpan oSpan = DateTime.Now - oInfo.LastWriteTime;
            if (oSpan.Days > RefreshAfterDays)
                fGetFile = true;
        }
        
        //Check date
        if (fGetFile)
        {
            oImgOriginal = FetchAndStoreImage(sUrl, sPhysicalFile, sStoreLocation);
        }
        else
        {
            oImgOriginal = System.Drawing.Image.FromFile(sPhysicalFile);
        }
        
        context.Response.ContentType = "image/jpeg";
        oImgOriginal.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
        oImgOriginal.Dispose();
    }


We start by declaring some global variables:

sStoreLocation : I have chosen to store the fetched images in app_data directory - or actually a subdirectory of it called fetchimages

RefreshAfterDays: when retrieving an image from our local cache - if it's more than  <RefreshAfterDays> days old we will fetch a new one

 Moving on - the sPhysicalFile variable will contain the whole physical path of the file - for example d:\code\web\test\app_data\fetchimages\www.aspcode.net.jpg

Now checking if file exists - if not we should retrieve a new file - if it does exist we check how old it is - it might be time to refetch it as stated above.

If we should get a new file for whatever reason we call the FetchAndStoreImage function:



    public System.Drawing.Image FetchAndStoreImage(string sUrl, string sPhysicalFile, string sStoreLocation)
    {
		HttpWebRequest request=
			(HttpWebRequest)WebRequest.Create("http://open.thumbshots.org/image.pxf?url=" + HttpUtility.UrlDecode(sUrl));
		request.Timeout = 10000; // 10 secs
		HttpWebResponse response = (HttpWebResponse)request.GetResponse();
		Stream resStream = response.GetResponseStream();

        System.Drawing.Image oImg;
        oImg = System.Drawing.Image.FromStream(resStream);
        if (oImg.Height == 1 && oImg.Width == 1)
        {
            oImg = System.Drawing.Image.FromFile( Path.Combine(sStoreLocation,"noimage.gif" ));
        }
        else
        {
            Stream localStream = null;
            localStream = File.Create(sPhysicalFile);

            oImg.Save(localStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            localStream.Close();
        }

        
		resStream.Close();
        return oImg;
    }




Here it's just a matter of retrieving it from thumbshots.org and storing it to the file. However, of the file couldn't be retrieved for some reason, thumbshots.org will send back a 1x1 pixels image - and we check for that:



        if (oImg.Height == 1 && oImg.Width == 1)
        {
            oImg = System.Drawing.Image.FromFile( Path.Combine(sStoreLocation,"noimage.gif" ));
        }

So if you want to use your own image for "not available" - just call it noimage.gif and put it inside the fetchimages directory.

Last - back in ProcessRequest - we write the image to the Response.OutputStream:

 




        context.Response.ContentType = "image/jpeg";
        oImgOriginal.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
        oImgOriginal.Dispose();
    }


 So please download the attached VS2005 solution and try it for yourself!

And remember - if you use it - please pay attention to the thumbshots.org license and put the Attribution on your pages looking like this:

 About Thumbshots thumbnails

 Disclaimer: aspcode.net makes no warranties of the correctness of this code. There might be some flaws which you might want to fix, an easy one which directly comes to mind is if the WebRequest fails - then we should return the Noimage.gif. Just a simple try/catch inside the FetchAndStoreImage should do it.

However for clarity - I have tried to keep it as clean as possible.