動的画像を生成するために呼び出されるasp.netハンドラーがあります(塗りつぶしレベルを示す丸いアイコンと、さまざまな塗りつぶしレベルでのさまざまな色)。画像は完全にメモリ内に生成され、プロセス中に画像ファイルは読み込まれません。このコードは本番環境では 99.9% の時間で動作しますが、ハンドラーが動作を停止し、以下の例外がスローされることがあります。IIS をリセットすると、問題が解決します。私は Windows Server 2008 r2 標準を実行しており、最新かつ最高の更新プログラムがすべて適用されています。以下に関連するコードを含めました。どんなアイデアでも大歓迎です。
私はすでに何十もの記事と Microsoft KB 記事を見てきましたが、それらのほとんどすべてがファイルとディレクトリのアクセス許可を中心に展開しています。それはここでは当てはまらないようです。
例外: System.Runtime.InteropServices.ExternalException: GDI+ で一般的なエラーが発生しました。System.Drawing.Image.Save (ストリーム ストリーム、ImageCodecInfo エンコーダー、EncoderParameters encodingParams) で System.Drawing.Image.Save (ストリーム ストリーム、ImageFormat 形式) で
コード:
var fillPercentString = context.Request.QueryString["fillPercent"];
var iconSizeString = context.Request.QueryString["size"];
var colorString = context.Request.QueryString["fillColor"];
double fillPercent;
double.TryParse(fillPercentString, out fillPercent); //0.01 * (!string.IsNullOrEmpty(fillPercentString) ? int.Parse(fillPercentString) : 0);
fillPercent = 0.01 * fillPercent;
var iconSize = !string.IsNullOrEmpty(iconSizeString) ? int.Parse(iconSizeString) : 16;
var iconWidth = iconSize;
var iconHeight = iconSize;
var memStream = new MemoryStream();
var color = System.Drawing.Color.FromName(colorString);
if (iconSize < 0)
{
throw new InvalidOperationException("Invalid size.");
}
if (fillPercent < 0 || fillPercent > 100)
{
throw new InvalidOperationException("Invalid fill percentage.");
}
using (var bitmap = new Bitmap(iconWidth + 1, iconHeight + 1))
using (var graphic = Graphics.FromImage(bitmap))
using (var backgroundFillBrush = new SolidBrush(Color.White))
using (var fillBrush = new SolidBrush(color))
using (var outlinePen = new Pen(Color.Black, 1f))
{
graphic.SmoothingMode = SmoothingMode.AntiAlias;
var circleBounds = new Rectangle(0, 0, iconWidth, iconHeight);
// fill with transparent
graphic.FillRectangle(backgroundFillBrush, 0, 0, bitmap.Width, bitmap.Height);
// fill a full circle
graphic.FillEllipse(fillBrush, circleBounds);
// draw a rectangle to clip out unneeded region
if (fillPercent < 1.00)
{
graphic.FillRectangle(backgroundFillBrush, new RectangleF(0, 0, bitmap.Width, (int)((1 - fillPercent) * bitmap.Height)));
}
// draw the circle outline
graphic.DrawEllipse(outlinePen, circleBounds);
// finalize and save to cache
bitmap.MakeTransparent(bitmap.GetPixel(1, 1));
bitmap.Save(memStream, ImageFormat.Png);
var returnBytes = memStream.ToArray();
// write the image to the output stream
if (context.Response.IsClientConnected)
{
context.Response.ContentType = "image/png";
context.Response.OutputStream.Write(returnBytes, 0, returnBytes.Length);
}
}