Generating GDI+ Images for ASP.NET MVC Views
This post is about applying the same technique I presented for ASP.NET Web Forms, but this time for MVC.
We need to have an ActionResult that does the actual work of converting whatever we draw in the Graphics context into an image with an inline Data URI. Here’s a possible solution, where you only specify the dimensions of the image to be generated:
public sealed class InlineImageResult : ActionResult
{
private readonly Image bmp;
public InlineImageResult(Int32 width, Int32 height)
{
//the PixelFormat argument is required if we want to have transparency
this.bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
this.Graphics = Graphics.FromImage(this.bmp);
//for higher quality
this.Graphics.CompositingQuality = CompositingQuality.HighQuality;
this.Graphics.SmoothingMode = SmoothingMode.HighQuality;
this.Graphics.InterpolationMode = InterpolationMode.High;
//make the background transparent
this.Graphics.Clear(Color.Transparent);
}
public Graphics Graphics { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
using (this.bmp)
using (this.Graphics)
using (var stream = new MemoryStream())
{
//PNG because of transparency
var format = ImageFormat.Png;
this.bmp.Save(stream, format);
var img = String.Format("<img src=\"data:image/{0};base64,{1}\"/>", format.ToString().ToLower(), Convert.ToBase64String(stream.ToArray()));
context.HttpContext.Response.Write(img);
}
}
}
Now, we need to create an instance of this result and draw in it, in a controller’s action method:
[ChildActionOnly]
public ActionResult Image()
{
var result = new InlineImageResult(200, 50);
result.Graphics.DrawString("Hello, World!", new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Blue), 0, 0);
return result;
}
Notice the ChildActionOnly attribute: it tells MVC that this action method is only meant to be used in child action (RenderAction) call, not as a stand-alone action, like this:
<p>
@{ Html.RenderAction("Image"); }
</p>
As you can see, this provides a very convenient way to generate images on the fly. You just need to learn about the drawing methods in GDI+.