しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

data URL スキームを作成するヘルパー

HTML5 と data URL scheme - しばやん雑記 で書いた data URL を ASP.NET MVC で使いやすくするためのヘルパーを作りました。

使い方はシンプルで Url.ToDataUrl メソッドを呼び出すだけです。

@* ファイルから data URL を作成する *@
<img src="@Url.ToDataUrl("~/Content/temp.png", "image/png")" />

そして ToDataUrl のソースはこんな感じです。

public static class UrlExtensions
{
    public static string ToDataUrl(this UrlHelper helper, string contentPath, string contentType)
    {
        // 仮想パスをサーバの物理パスにマッピングする
        var path = helper.RequestContext.HttpContext.Server.MapPath(contentPath);

        // ファイルをバイト列として読み込む
        var bytes = File.ReadAllBytes(path);

        // data URL scheme の形にして出力
        return string.Format("data:{0};base64,{1}", contentType, Convert.ToBase64String(bytes));
    }
}

本来ならば MIME type を拡張子から判別してもいいんですが、IIS が持っている MIME map を取得する方法がなかったので指定する形にしました。

追記

内部に拡張子と MIME の対応表を持たせて、自動で出力するバージョンも作りました。

public static class UrlExtensions
{
    private static readonly Dictionary<string, string> MimeMapping = new Dictionary<string, string>
    {
        { ".txt", "text/plain" },
        { ".html", "text/html" },
        { ".xml", "text/xml" },
        { ".css", "text/css" },
        { ".js", "text/javascript" },
        { ".jpg", "image/jpeg" },
        { ".jpeg", "image/jpeg" },
        { ".png", "image/png" },
        { ".gif", "image/gif" },
    };

    public static string ToDataUrl(this UrlHelper helper, string contentPath)
    {
        var path = helper.RequestContext.HttpContext.Server.MapPath(contentPath);

        var bytes = File.ReadAllBytes(path);

        var extension = Path.GetExtension(contentPath);

        string contentType;

        if (!MimeMapping.TryGetValue(extension, out contentType))
        {
            contentType = "application/octet-stream";
        }

        return string.Format("data:{0};base64,{1}", contentType, Convert.ToBase64String(bytes));
    }
}

該当する MIME がない場合には application/octet-stream になります。