An ASP.NET handler that returns a dynamically generated image
<%@ WebHandler Language="C#" Class="ImageHandler" %>
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using System.Web.Caching;
public class ImageHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
// Get the image ID from querystring, and use it to generate a cache key.
String imageID = context.Request.QueryString["PhotoID"];
String cacheKey = context.Request.CurrentExecutionFilePath + ":" + imageID;
Byte[] imageBytes;
// Check if the cache contains the image.
Object cachedImageBytes = context.Cache.Get(cacheKey);
if (cachedImageBytes != null)
{
imageBytes = (Byte[])cachedImageBytes;
}
else
{
// Get image from business layer, and save it into a Byte array as JPEG.
Image im = PhotoLibrary.GetImage("PhotoID");
MemoryStream stream = new MemoryStream();
im.Save(stream, ImageFormat.Jpeg);
stream.Close();
im.Dispose();
imageBytes = stream.GetBuffer();
// Store it in the cache (to be expired after 2 hours).
context.Cache.Add(cacheKey, imageBytes, null,
DateTime.MaxValue, new TimeSpan(2, 0, 0),
CacheItemPriority.Normal, null);
}
// Send back image.
context.Response.ContentType = "image/jpeg";
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.BufferOutput = false;
context.Response.OutputStream.Write(imageBytes, 0, imageBytes.Length);
}
public bool IsReusable {
get {
return false;
}
}
}
Use HTTP Handlers to Generate Images Dynamically
Including an image in a Web page is as simple as inserting an <img> tag into the page's HTML. The following statement displays the image in the file named Logo.jpg:
<img src="logo.jpg">
This is fine and good if Logo.jpg contains a static image that can be generated absent any user input. But what if you want to build a Web page that displays images built at run time from user input—for example, a page that graphs user-supplied data or values obtained from a database? The simple answer is that you create the image on the server and return an <img> tag that references it. The reality is that dynamic image generation is easier said than done
PieChart.aspx
<html>
<body>
<form runat="server">
<table width="100%">
<tr>
<td>
<table cellpadding="8" bgcolor="gainsboro">
<tr>
<td>Q1</td>
<td><asp:TextBox ID="Q1" RunAt="server" /></td>
</tr>
<tr>
<td>Q2</td>
<td><asp:TextBox ID="Q2" RunAt="server" /></td>
</tr>
<tr>
<td>Q3</td>
<td><asp:TextBox ID="Q3" RunAt="server" /></td>
</tr>
<tr>
<td>Q4</td>
<td><asp:TextBox ID="Q4" RunAt="server" /></td>
</tr>
<tr>
<td></td>
<td align="right">
<asp:Button Text="Show Chart" OnClick="OnShowChart"
RunAt="server" />
</td>
</tr>
</table>
</td>
<td>
<asp:Image ID="Chart" AlternateText="Pie Chart"
RunAt="server" />
</td>
</tr>
</table>
</form>
</body>
</html>
<script language="C#" runat="server">
void OnShowChart (Object sender, EventArgs e)
{
Chart.ImageUrl = String.Format
("PieChart.ashx?q1={0}&q2={1}&q3={2}&q4={3}" +
"&width=256&height=224", Q1.Text, Q3.Text, Q3.Text,
Q4.Text);
}
</script>
PieChart.ashx
<%@ WebHandler Language="C#" Class="PieChartGenerator" %>
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
public class PieChartGenerator : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
//
// Extract input parameters from the query string
//
decimal[] vals = new decimal[4];
vals[0] = Convert.ToDecimal (context.Request["q1"]);
vals[1] = Convert.ToDecimal (context.Request["q2"]);
vals[2] = Convert.ToDecimal (context.Request["q3"]);
vals[3] = Convert.ToDecimal (context.Request["q4"]);
int width = Convert.ToInt32 (context.Request["width"]);
int height = Convert.ToInt32 (context.Request["height"]);
//
// Create a bitmap, draw a pie chart, and write it to the
// response.
//
Bitmap bitmap = new Bitmap (width, height,
PixelFormat.Format32bppArgb);
Graphics g = Graphics.FromImage (bitmap);
DrawPieChart (g, Color.White, vals, width, height);
context.Response.ContentType = "image/gif";
bitmap.Save (context.Response.OutputStream, ImageFormat.Gif);
//
// Clean up and return.
//
bitmap.Dispose ();
g.Dispose ();
}
public bool IsReusable
{
get { return true; }
}
void DrawPieChart (Graphics g, Color bkgnd, decimal[] vals,
int width, int height)
{
//
// Erase the background.
//
SolidBrush br = new SolidBrush (bkgnd);
g.FillRectangle (br, 0, 0, width, height);
br.Dispose ();
//
// Create an array of brushes.
//
SolidBrush[] brushes = new SolidBrush[6];
brushes[0] = new SolidBrush (Color.Red);
brushes[1] = new SolidBrush (Color.Yellow);
brushes[2] = new SolidBrush (Color.Blue);
brushes[3] = new SolidBrush (Color.Cyan);
brushes[4] = new SolidBrush (Color.Magenta);
brushes[5] = new SolidBrush (Color.Green);
//
// Sum the inputs.
//
decimal total = 0.0m;
foreach (decimal val in vals)
total += val;
//
// Draw the chart.
//
float start = 0.0f;
float end = 0.0f;
decimal current = 0.0m;
for (int i=0; i<vals.Length; i++) {
current += vals[i];
start = end;
end = (float) (current / total) * 360.0f;
g.FillPie (brushes[i % 6], 0.0f, 0.0f, width, height,
start, end - start);
}
//
// Clean up and return.
//
foreach (SolidBrush brush in brushes)
brush.Dispose ();
}
}
it includes an image control that initially displays no image at all because its ImageUrl property is unassigned. Clicking the Show Chart button activates the OnShowChart method on the server. OnShowChart builds a URL complete with a query string containing user input and assigns it to the Image control. Entering the values 100, 200, 300, and 400 into the four TextBoxes produces the following URL:
piechart.ashx?q1=100&q2=200&q3=300&q4=400&width=256&height=224
Note the resource identified in the URL: PieChart.ashx. Inside PieChart.ashx is an HTTP handler that generates pie charts from the inputs in the query string. The @ WebHandler directive at the top of the file informs ASP.NET that PieChart.ashx contains an HTTP handler. ASP.NET automatically compiles and executes the handler when the ASHX file is requested. No special registration is required because Machine.config maps ASHX files to a handler that knows how to compile and run other HTTP handlers.
0 comments:
Post a Comment