15. 高機能カウンタ

トップどんと来い! ASP.NET > 15. 高機能カウンタ

機能

カウンタとして実用的な、いや高機能なものを作りたいと思います。
前回のカウンタはページの中にあるものですが、今回は画像をサーバ上で生成し、しかも普通の画像のようにそれを呼び出したいと思います。

この機能はアイライトさんのサイトにありましたから、それを利用させていただきました。

もう1つの機能は「1つのカウンタでどのページでもカウントできる」という機能です。
普通のカウンタは1つで1つのページしかカウントできませんが、このカウンタではいくらでもカウントを取れます。

1つはトップページにつけて、掲示板にもつけて、迷コラムにもつけて、それぞれのページのカウント数を取得できるということです。

とはいえ、大変簡単です。この機能を実装するポイントはクエリです。

クエリ

調べると、クエリは「6. Page クラス」でやってますね。
私自身、どこでやったか忘れていました。

よって詳しくはしませんが、いくつかの処理を加えてみましょう。
string page = Request.QueryString["page"];

if (page == null) page = "index";

if (!File.Exists(Server.MapPath(".") + "\\" + page + ".txt"))
{
    StreamWriter sw2 = new StreamWriter(Server.MapPath(".") + "\\" + page + ".txt");
    sw2.Write("1");
    sw2.Close();
}
ページの名前をクエリで渡されて、それを page 変数に代入します。
その際、クエリが空っぽ(null 参照)ならば、index を代入します。

index は基本的にトップページの名前ですから、トップページから呼び出す際は何もクエリを指定しなくていいことになります。

そしてまた、その下の処理は大変重要です。
もしこの処理がなければいちいちファイルを手作りしなければなりません。

if の判別式を見てください。最初の「!」を見落とすといくら人が着てもカウントは1のままになります。
! があるおかげで「なになにでないとき」という否定の処理になりますので、ファイルがないときにはファイルを作るという処理になります。

これ以降は前回のカウンタと同じです。

画像の生成

Bitmap bitmap = new Bitmap(75, 22);
Graphics graphics = Graphics.FromImage(bitmap); 

string stringText = count;
Font fonLable = new Font("MS ゴシック", 15);

graphics.FillRectangle(Brushes.Black, 0, 0, 100 , 22);
graphics.DrawString(stringText, fonLable, Brushes.White,0,0);

Response.ClearContent();
Response.ContentType = "image/gif";
bitmap.Save(Response.OutputStream, ImageFormat.Gif);
Response.End();

graphics.Dispose();
bitmap.Dispose();
このソースはアイライトさんのところのソースコードを拝借し、大きさや色をカウンタにあうように変えただけです。
簡単に説明していきましょう。

1行目は Bitmap オブジェクトの生成を行っています。このコンストラクタでサイズの設定をしています。
このサイズはステップアップC# に合うように5から6桁用です。サイズの変更は x 軸だけでいいでしょう。

次は Graphics オブジェクトです。FromImage() というのは引数に Bitmap をとり、Graphics オブジェクトを返します。

次は表示する文字列です。count は string 型で、すでにファイルから取得したカウント数が入っています。
その次の行ではフォントの設定をしています。アイライトさんのものは明朝でしたが、カウンタにはゴシックが合います。第2引数は太さですね。

次は黒で塗りつぶして、カウント数を白で書いてるところです。

この後が面白い。
この作業は一連として扱う必要があります。画像を生成し、Outut(出力)します。
ここで「画像 gif」であることをしてしており、End() で出力処理が終わります。

ここは形式を変えることで XML などにも対応できます。やはり最も多く利用されるのは画像だと思いますが、大変便利です。
一連の作業と覚えておけば、いくらでも応用が利きます。

最後の2行はオブジェクトの破棄です。
Graphics や Bitmap などは放っておくと負担を掛けてしまいますから、Web アプリでは特に気をつけなければなりません。

ソース

<%@ Page language="c#" %>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Drawing.Imaging" %>
<%@ import Namespace="System.Drawing" %>

<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
    string page = Request.QueryString["page"];
    
    if (page == null) page = "index";
    
    if (!File.Exists(Server.MapPath(".") + "\\" + page + ".txt"))
    {
        StreamWriter sw2 = new StreamWriter(Server.MapPath(".") + "\\" + page + ".txt");
        sw2.Write("1");
        sw2.Close();
    }
    
    StreamReader sr = new StreamReader(Server.MapPath(".") + "\\" + page + ".txt");
    string count = sr.ReadToEnd();
    sr.Close();

    int i = int.Parse(count);
    i++;
    StreamWriter sw = new StreamWriter(Server.MapPath(".") + "\\" + page + ".txt");
    sw.Write(i.ToString());
    sw.Close();

    Bitmap bitmap = new Bitmap(75, 22);
    Graphics graphics = Graphics.FromImage(bitmap); 

    string stringText = count;
    Font fonLable = new Font("MS ゴシック", 15);

    graphics.FillRectangle(Brushes.Black, 0, 0, 100 , 22);
    graphics.DrawString(stringText, fonLable, Brushes.White,0,0);

    Response.ClearContent();
    Response.ContentType = "image/gif";
    bitmap.Save(Response.OutputStream, ImageFormat.Gif);
    Response.End();

    graphics.Dispose();
    bitmap.Dispose(); 
}

</script>
上のほうの Namespace の追加を忘れないように。
このソースには script タグしか含まれません。html などの Visual 部品は要りませんので気をつけてください。