ASP.NETの小技!―画像ファイルをサイズ指定表示する

とても久しぶりに、「新館」の方に手を付けてみようという気になった(というか、まったくのほったらかしなのであったが)。で、いろいろ触っているのだが、トップページが殺風景なので、ランダムにサイト内の画像でも表示させてみよう、という気になる。ランダムに画像を選ぶ方法はさておき、最初は選んだ画像を<img>タグのWIDTH属性でサイズ指定していたが、大きな画像だと無意味にダウンロードサイズが大きくなってしまう。そこで、サーバ側でリサイズを行い、それをクライアントに送り返すことを考えた。

リンク:なおさん亭::新館

通常、<img>タグのSRC属性には静的画像へのURLを指定するが、今回はここにASP.NETファイル(.aspx)を指定して、動的に返される画像を表示することにする。このASP.NETファイルは、引数にimageとしてもとの画像ファイルのパス(サーバ内)、sizeとして長い方の辺のピクセル数を指定する。とすると、<img>タグは以下のようになる(SRC属性以外は省略)。

<img src="~/showimage.aspx?image=~/image/xxxx.jpg&size=320">

問題は、showimage.aspxの中身であるが、

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Imaging" %>

<script runat="server">
    protected void Page_Load(Object sender, EventArgs e){
        string filename = Request.QueryString["image"];
        filename = Server.MapPath(filename);
        Bitmap bmp = new Bitmap(filename);
        int w = bmp.Width;
        int h = bmp.Height;
        int t = Int16.Parse(Request.QueryString["size"]);
        if (w > h)
        {
            h = (h * t) / w;
            w = t;
        }
        else
        {
            w = (w * t) / h;
            h = t;
        }
        Bitmap newbmp = new Bitmap(w, h, PixelFormat.Format24bppRgb);
        Graphics graph = Graphics.FromImage(newbmp);
        graph.DrawImage(bmp, 0, 0, w, h);
        Response.ContentType = "image/jpeg";
        newbmp.Save(Response.OutputStream, ImageFormat.Jpeg);
        Response.End();
        newbmp.Dispose();
        graph.Dispose();
    }
</script>

とまぁ、こんな感じである。

キモは、

  1. 元画像のためのBitmapオブジェクトを用意し、
  2. 新画像のためのBitmapオブジェクトも用意し、
  3. 新画像に画像を転写するためのGraphicsオブジェクトも用意し、
  4. 画像を転写し、HTTP出力ストリームに書き出す。

といった流れになる。元画像のBitmapオブジェクトで直接リサイズできたり、Graphicsオブジェクトなぞ使わずに転写を行いたいところだが、GDI+の構造からこれはできない。だが、できあがった画像にMIMEタイプを指定し、単に書き出せば済むあたりは、フレームワークを使うメリットである。

この方法を使うと、単に拡大、縮小するというほかに、文字を入れたり、画像の調整をしたり、いろいろな加工処理を間に挟むことができるので、応用範囲が広い。難点は、サーバに負荷がかかることで、静的画像を単に送り出すことに比べると比べものにならない。なので、ページ内に何枚も画像がある場合、すべてに使うようなことは避けるべきである。

実際の動きは、「新館」のトップページで確かめて欲しい(単に画像が出るだけだが、画像のパスを見るとASP.NETファイルになっているはずである)。

コメント