Image thumbnail Html helper with image caching for the perforance

Creating image thumbnail with caching in MVC

Creating image thumbnail on the fly is pretty easy in ASP.NET whether you are still using WebForms or MVC. There is even a methods introduced in .NET 4.5 framework for generating thumbnail image from a Bitmap class instance.

You can easily create and action in a controller and generate and return thumbnail image on the fly. The problem is that Bitmap object takes a big chunk of memory when instantiated. If you are generating thumbnail on the fly, a big piece of memory will be taken on every request.

Although memory used by Bitmap instance will be released after request, this might be a bottle neck for you application under heavy traffic. Basically you are using processor power to return a thumbnail of a file which is probably generated for some other request. This means you will create instances of the same bitmap but for different requests, which is a bit waste of processor power.

Nice thing would be to store this generated bitmap as a file and return only file previously generated to all of the requests.

I have created a small HtmlHelper which does this

public static class HtmlHelpers
{
public static MD5 md5 = MD5.Create();
public static IHtmlString HtmlImageThumbnail(string imagePath, int width, int height, string alt = null, string @class = null)
{
return HtmlImageThumbnail(imagePath, new Size(width, height), alt, @class);
}
public static IHtmlString HtmlImageThumbnail(string imagePath, Size size, string alt = null, string @class = null)
{
var cacheFolder = "/ImageCache/";
var context = HttpContext.Current;
var path = context.Server.MapPath(imagePath);
var hashName = string.Concat(GetMd5Hash(string.Concat(path.Trim().ToLower(), "-", size.Width, "x", size.Height)), Path.GetExtension(imagePath).ToLower());
var cachedImagePath = context.Server.MapPath(Path.Combine(cacheFolder, hashName));
if (!File.Exists(cachedImagePath) && File.Exists(path))
{
using (Bitmap bmp = new Bitmap(path))
{
         bmp.GetThumbnailImage(size.Width, size.Height, null, IntPtr.Zero).Save(cachedImagePath);
                }
            }

            var src = string.Concat(cacheFolder, hashName);

            XElement imgTag = new XElement("img", new XAttribute("src", src), new XAttribute("alt", !String.IsNullOrWhiteSpace(alt) ? alt : string.Empty), new XAttribute("class", !String.IsNullOrWhiteSpace(@class) ? @class : string.Empty));

            return new HtmlString(imgTag.ToString());
        }

        private static string GetMd5Hash(string input)
        {
            byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }
    }
    

For generating thumbnail I used GetThumbnail methods on the Bitmap class instance, which is not my favorite, but for the sample purposes, this will work just fine. I prefer using some method I developed some time ago which you can find in this article on my blog.

These HtmlHelper is a part of mini project hosted on Github so you can fork it or download a source code to include in your project.

It can be easily used in any MVC Razor view just like any other HtmlHelper.

@WebOptimization.HtmlHelpers.HtmlImageThumbnail("/images/pebbles.jpg", 200, 200)
    

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.


About the author

DEJAN STOJANOVIC

Dejan is a passionate Software Architect/Developer. He is highly experienced in .NET programming platform including ASP.NET MVC and WebApi. He likes working on new technologies and exciting challenging projects

CONNECT WITH DEJAN  Loginlinkedin Logintwitter Logingoogleplus Logingoogleplus

JavaScript

read more

SQL/T-SQL

read more

Umbraco CMS

read more

PowerShell

read more

Comments for this article