.NET TIPS [ASP.NET]動的にJPEG画像を作成するには?山田 祥寛2005/09/30 |
|
|
データベースなどのデータ・ストアに蓄積されたデータは、何もDataGridコントロールなどでグリッド表示するばかりが能ではない。時として、円グラフや折れ線グラフなどのチャート画像に加工することで、よりユーザーの視覚に訴えるビューを実現できるケースも多いはずだ。
ASP.NETには、チャートを描画するためのコントロールは標準では用意されていないが、.NET Frameworkには、Windows標準の描画エンジンであるGDI+(Graphical Device Interface +)機能にアクセスするためのクラス・ライブラリが用意されている。本稿では、このクラス・ライブラリを利用して、テキスト・ファイル上で管理された数値データを基に、動的に円グラフを生成してみることにしよう。
なお、本稿のサンプルを動作させるには、あらかじめグラフの基となる数値データとして、以下のようなタブ区切りテキスト(dotnet.dat)を用意しておく必要がある。
1. | すばらしい | 123 |
2. | 良かった | 102 |
3. | 普通 | 57 |
4. | 悪い | 10 |
5. | なってない | 3 |
円グラフ描画の基となるタブ区切りテキスト(dotnet.dat) |
それではさっそく、具体的な手順を見ていくことにしよう。
1. 画像生成用のHTTPハンドラ・クラスを記述する
本稿の例のように、ASP.NET上で画像データを生成するには、HTTPハンドラ・クラスを利用すると便利だ。HTTPハンドラ・クラスとは、IISに対してクライアントから要求があった場合に、実際のリクエスト処理を行うためのクラスで、例えばおなじみの.aspxファイルも内部的にはHTTPハンドラ・クラスによって処理されている。
初歩的なASP.NETアプリケーションを構築するうえでは、HTTPハンドラ・クラスを意識する必要はほとんどないが、アプリケーションに新たなサービスを定義したい場合などでは、HTTPハンドラ・クラスを利用することでスマートにサービスを実装することができる。
自前のHTTPハンドラ・クラスを作成する方法については、本稿では割愛する。詳細は、「TIPS:[ASP.NET]ASP.NETアプリケーションに独自の拡張子を追加するには?」)を参照いただきたい。
以下は、データ・ファイルから読み込んだデータを基に円グラフの画像を生成してレスポンスとして返すHTTPハンドラである。
|
|
数値データから動的に円グラフを生成するHTTPハンドラ・クラス(C#版:ImageGenerator.cs) |
|
|
数値データから動的に円グラフを生成するHTTPハンドラ・クラス(VB.NET版:ImageGenerator.vb) |
Bitmapクラス、Graphicsクラス(System.Drawing名前空間)に関する基本は、ビットマップに関する各TIPSとコード内のコメントを参照していただくとして、ここでは円グラフを出力するロジックを追ってみることにしよう。
円グラフを構成する円弧を出力するのは、GraphicsクラスのFillPieメソッドの役割だ。本稿で使用しているFillPieメソッドの構文は、以下のとおり。
|
||
Graphics.FillPieメソッドのシグネチャ(上:C#、下:VB.NET) |
FillPieメソッドのパラメータは、先頭から「使用するブラシ」「中心のX座標」「中心のY座標」「高さ」「幅」「開始角度」「描画角度」である。つまり、ここでは−90度を開始角度(start)とし、各データ項目の角度(angle)を加算しながら円弧を描画することで、円弧を順番に積み重ね、1つの円グラフを生成しているというわけだ。
生成した画像(Graphicsオブジェクト)は、最終的にBitmapオブジェクトのSaveメソッドで出力できる。本稿で使用しているSaveメソッドの構文は、以下のとおり。
|
||
Bitmap.Saveメソッドのシグネチャ(上:C#、下:VB.NET) |
このメソッドでは、指定された出力先(Streamオブジェクト)に対して、指定フォーマット(ImageFormatオブジェクト)で画像を出力することができる。ImageFormatオブジェクト(System.Drawing.Imaging名前空間)のプロパティには、本稿で使用しているJPEG画像のほか、Bmp、Exif、Gif、Png、Tiffなど主要な画像形式を指定可能だ。
また、画像データのようなバイナリ・データをクライアントに出力したい場合には、バイナリ出力ストリームを利用すること。バイナリ出力ストリームは、HttpResponseオブジェクトのOutputStreamプロパティで取得できる。
2. HTTPハンドラ・クラスを配置する
HTTPハンドラ・クラスは、使用に先立ってコマンド・プロンプトからコンパイルを行う必要がある。コンパイルの構文は以下のとおり。
|
||
HTTPハンドラ・クラスのコンパイル方法(上:C#、下:VB.NET) |
上記のコンパイルに成功した場合、C#、VB.NETいずれにおいてもImageGenerator.dllが生成されるはずなので、これをアプリケーション・ルート配下の「\bin」フォルダにコピーすればよい。
3. web.configの設定を行う
次に、アプリケーション・ルート配下のweb.configに以下の設定を追加する。「TIPS:[ASP.NET]特定の拡張子に対するアクセスを制限するには?」でも紹介したように、これによって、いま作成したImageGenerator.dllアセンブリ内のImageGeneratorクラス(Com.Msn.Wings名前空間)が拡張子「.img」処理用のHTTPハンドラ・クラスとして追加される。
|
|
拡張子「.img」の設定を追加したweb.config |
<httpHandlers>要素配下の<add>要素のpath属性に「*.img」のようなワイルドカードを含んだパスを指定することで、拡張子「.img」に対するリクエストをすべてImageGeneratorクラスで処理できるというわけだ。
前述のImageGenerator.cs(ImageGenerator.vb)のソース・コードをご覧いただければ分かるように、後はリクエストURLから動的に処理を分岐するロジックを、HTTPハンドラ・クラスに追加すればよい。
ここでは、リクエストURLから拡張子を取り除いたベース名を抽出し、StreamReaderクラス(System.IO名前空間)で「<ベース名>.dat」をデータ・ファイルとして読み込んでいる。このような仕組みを採用することで、リクエストURLを変えれば、参照すべきデータ・ファイルを動的に変更できるというわけだ。汎用的なサービスを提供する場合にはよく利用する手法なので、覚えておくとよいだろう。
4. IISに拡張子のマッピングを行う
ただし、ASP.NET標準でない拡張子を追加した場合、web.configの設定だけではHTTPハンドラ・クラスは正しく実行できない。というのも、HTTPハンドラ・クラスへの振り分けはASP.NETエンジン(aspnet_isapi.dll)が行うからだ。「.img」はIISのデフォルト設定では認識されない拡張子であるから、当然、拡張子「.img」へのリクエストがあってもaspnet_isapi.dllは起動しない。
自前の拡張子を認識させるには、IIS上で拡張子「.img」とASP.NETエンジンとのマッピングを行う必要がある。この方法については、「TIPS:[ASP.NET].htmlや.pdfファイルをフォーム認証やロギングの対象にするには?」で紹介しているので、そちらを参照してほしい。
■
以上で、サンプル・アプリケーションを動作させるための一連の作業は完了だ。ImageGeneratorクラスの動作を確認するために、以下のようなWebフォームを作成しよう。
|
|
ImageGeneratorを利用するためのWebフォーム(showImage.aspx) |
画像データを出力するImageGeneratorクラスは、<img>タグのsrc属性からあたかも静的な画像ファイルであるかのように呼び出すことが可能だ。以上を実行した結果、以下のような結果が出力されれば成功だ。
showImage.aspxの実行結果 |
異なるデータ・ファイルを作成し、出力画像が動的に切り替わることも確認していただきたい。なお、本稿ではデータ項目の数が5つ以内であることを前提としているが、当然、5つ以上の項目に対応することも可能だ。余力のある方は、ぜひ挑戦してみていただきたい。
カテゴリ:Webフォーム 処理対象:グラフ 使用ライブラリ:Bitmapクラス(System.Drawing名前空間) 使用ライブラリ:Graphicsクラス(System.Drawing名前空間) 使用ライブラリ:ImageFormatクラス(System.Drawing.Imaging名前空間) 関連TIPS:[ASP.NET]ASP.NETアプリケーションに独自の拡張子を追加するには? 関連TIPS:[ASP.NET]特定の拡張子に対するアクセスを制限するには? 関連TIPS:[ASP.NET].htmlや.pdfファイルをフォーム認証やロギングの対象にするには? |
「.NET TIPS」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|