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+.

Published by

Ricardo Peres

Team Leader at Dixons Carphone. Microsoft MVP.

Leave a Reply

Your email address will not be published. Required fields are marked *