When I published my article about caching images in ASP.NET I got some questions if it is possible to do this with dynamically generated images. The answer is yes. In the following sample I will show how it works.
As explained in the article I implement a custom http handler for the image. But this time I do not load an image from the file system, but I generate a new one. For this purpose I create a new Bitmap object to which I add a string with the current date and time and a rectangle. Then I save the image to a MemoryStream object to convert it to a byte array. Now the interesting part starts. Just as with static files I configure the HttpCachePolicy object to cache the generated image on the client for one minute. Finally I add the content-disposition header to set the filename. This time I use BinaryWrite instead of WriteFile to send the image to the client.
namespace SoftwareArchitects.Web
{
public class DateTimeImageHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
Bitmap dateTimeImage = new Bitmap(220, 50);
Graphics dateTimeGraphics = Graphics.FromImage(dateTimeImage);
dateTimeGraphics.DrawString(
DateTime.Now.ToString(),
new Font("Verdana", 14),
new SolidBrush(Color.Blue),
new PointF(0, 0));
dateTimeGraphics.DrawRectangle(
new Pen(new SolidBrush(Color.Green)),
new Rectangle(0, 0, 219, 49));
MemoryStream stream = new MemoryStream();
dateTimeImage.Save(stream, ImageFormat.Png);
dateTimeGraphics.Dispose();
byte[] image = new byte[stream.Length];
stream.Position = 0;
stream.Read(image, 0, (int)stream.Length);
stream.Close();
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(1));
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetValidUntilExpires(false);
context.Response.AddHeader("content-disposition",
"inline; filename=DateTime.png");
context.Response.BinaryWrite(image);
}
}
}
All I have to do to use the new http handler is to add it to the httpHandlers section of web.config.
type="SoftwareArchitects.Web.DateTimeImageHandler,
SoftwareArchitects.Web.DateTimeImageHandler"/>
Now I can add an image to my .aspx page with the source "DateTime.png.ashx". As this file does not exist the path does not matter as long the filename does match the entry in the httpHandlers section in web.config. So I could as well choose the source "MyFolder/DateTime.png.ashx".
...

Reload page ...
...
When I run the page the generated image is displayed. It shows the current date and time. For the next minute the image will not change when I reload the page by doing a post back or by clicking the link (I set the caching duration to one minute in the http handler). When I reload the page after the image has expired a new image will be generated and displayed.
You can force IE to reload cached content by pressing CTRL + F5.
