ASP.NET MVC ImageHandler for thumbnails

As some of you might know, I am a really big fan of community-driven technologies. I also like to contribute myself in order to exchange new ideas and meet new people with common interests.Since I am quite new to ASP.NET MVC, I was thinking I would submit my first contribution : handling all your images through a custom actionresult/controller.
This allows me to do several things :

  • uniform access to images
  • possibility for custom types (this example ALWAYs renders as PNG)
  • generation of thumbnails.

Let's start with the code for the ActionResult (initially inspired by/copy-pasted from this , but since the new RC it is my own code):

using System.IO;
using System.Web.Mvc;
using System.Drawing;
using System.Drawing.Imaging;

namespace Be.Corebvba.MVC
{
 
public class ImageResult : FileStreamResult
  {

    public ImageResult(Image input):this(input,input.Width,input.Height) { }

    public ImageResult(Image input, int width,int height) :
      
base(
         GetMemoryStream(input,width,height,
ImageFormat.Png),
        
"image/png") 
   { }

   
static MemoryStream GetMemoryStream(Image input,int width,int height,ImageFormat fmt)
    {
       // maintain aspect ratio
      
if (input.Width > input.Height)
          height = input.Height * width / input.Width; 
       else
         
width = input.Width * height / input.Height;
      
      
var bmp = new Bitmap(input, width, height);
       var ms = new MemoryStream();
       bmp.Save(ms,
ImageFormat.Png);
       ms.Position = 0;
      
return ms;
     }
   }
}

The code for the controller is pretty straighforward as well :

public ActionResult ThumbImage(int id,int width,int height)
{
  
var d = _rDocument.GetById(id);
  
Image i=null;
  
try
  
{
      i =
Image.FromFile(d.PhysicalFilename);
     
return new Be.Corebvba.MVC.ImageResult(i, width, height);
   }
  
catch (Exception ex)
   {
      i =
new Bitmap(1, 1);
     
return new Be.Corebvba.MVC.ImageResult(i,1,1);
   }
  
finally
  
{
     
if (i != null) i.Dispose();
   }
}

This does need some better errorhandling, but I suppose you get the idea… (The _rDocument is a pointer to a Document repository which stores physical files. If you access your images from a database, you could simply use Image.FromStream instead of an Image.FromFile .In my document i reference the image as follows, et voila, automatic thumbnails :

<% var imgurl = Url.Action("ThumbImage", "Documents", new { id = d.ID,width=100,height=100 }); %>
<img src="<%=imgurl %>" style="float:left"/> 

comments powered by Disqus