2015年9月28日月曜日

ASP.NETで動的に画像を生成して返す(IHttpHandler版)

ASP.NETで動的に画像を生成して返すようなときは、WebFormを使用するのが一般的なようです。

この記事ではIHttpHandlerインターフェイスを実装して画像を生成して返す方法を紹介します。
以下2つの手順に従います。

  1. IHttpHandlerインターフェイスを実装した画像を出力するクラスを実装する
  2. 1のクラスをweb.configファイルへ登録する
まず「IHttpHandlerインターフェイスを実装した画像を出力するクラスを実装する」について説明します。このクラスのポイントは3つあります。
  1. IHttpHandlerインターフェイスを実装すること
  2. 画像のバイナリデータをHTTPレスポンスへ出力すること
  3. Content-Typeヘッダを適切に設定すること
次のサンプルプログラム(一部)をご覧ください。
namespace HttpHandlerSample
{
    // 動的にPNG画像を生成するクラス
    public class PngHandler : IHttpHandler
    {
        // このオブジェクトが再利用可能かを返すプロパティ
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }

        // ...略...

        // HTTPリクエストを処理するメソッド
        public void ProcessRequest(HttpContext context)
        {
            // 画像を生成する
            using (var image = GenerateImage())
            {
                // PNG形式でHTTPレスポンスへ出力する
                var output = context.Response.OutputStream;
                image.Save(output, ImageFormat.Png);
                output.Flush();
            }

            // Content-TypeヘッダをPNG形式に設定する
            context.Response.ContentType = "image/png";
        }

        // ...略...

    }
}

IHttpHandlerにはIsReusableプロパティとProcessRequestメソッドが定義されています。このProcessRequestメソッドを実装することで機能を実現します。
画像のバイナリデータを出力するには、Image#Saveメソッドを使用します。
Content-Typeヘッダを指定するには、HttpResponse#ContentTypeプロパティを使用します。画像の形式が一致するように設定します。

次に、上のクラスをweb.configへ以下のように設定します。
<configuration>
  <system.webServer>
    <handlers>
      <add name="PngHandler" path="*.png" verb="GET" type="HttpHandlerSample.PngHandler"/>
    </handlers>
  </system.webServer>
</configuration>
ちなみに

以上で動的な画像の生成が実現できます。
以下、サンプルコード全体です。