私は、しばらくの間、次の Global.asax (Application_Start) コードのほとんどを使用してきました (関連)。リクエストが外部から開始された場合(ホットリンク/ダイレクトリクエスト)、特定のディレクトリに透かし入りの画像を提供するように、このように構成しました。
//ImageResizer
Config.Current.Pipeline.Rewrite += delegate(IHttpModule mysender, HttpContext context, IUrlEventArgs ev)
{
if (context.Request.UrlReferrer == null || (context.Request.UrlReferrer != null && context.Request.UrlReferrer.Host != "www.mydomain.com"))
{
//File has been requested from outside of the target domain, so see if it meets criteria for watermarking
string folder1 = VirtualPathUtility.ToAbsolute("~/images/products");
string folder2 = VirtualPathUtility.ToAbsolute("~/images/product-showcase");
if (ev.VirtualPath.StartsWith(folder1, StringComparison.OrdinalIgnoreCase) || ev.VirtualPath.StartsWith(folder2, StringComparison.OrdinalIgnoreCase))
{
//Image is within the targeted folders. If the requested file is jpg, change extension to png
if (Path.GetExtension(ev.VirtualPath) == ".jpg") ev.VirtualPath = Path.ChangeExtension(ev.VirtualPath, ".png");
//Estimate final image size, based on the original image being 300x300.
System.Drawing.Size estimatedSize = ImageBuilder.Current.GetFinalSize(new System.Drawing.Size(300, 300), new ResizeSettings(ev.QueryString));
if (estimatedSize.Width > 100 || estimatedSize.Height > 100)
{
//It's over 100px, apply watermark and change the ouput format
ev.QueryString["watermark"] = "style";
ev.QueryString["bgcolor"] = "ffffff";
ev.QueryString["format"] = "jpg";
}
}
}
};
ただし、&format=jpg クエリ文字列を追加して製品画像が表示されるように、Web ページを変更しただけです。適切な MIME タイプが Web ブラウザに提供されることは理解しています。これは非常にすばらしいことですが、ファイル名はどうでしょうか。たとえば、/images/products/widget1.png?watermark=c&format=jpg は、提供される形式が jpg であっても png 画像を参照します。私が懸念しているのは、Google Images のようなスクレーパーまたは画像アグリゲーターが、1) URL をファイル名にまで削除したい、または 2) MIME タイプを考慮して拡張子を変更して再参照する可能性があることです。上記のような URL で Google 画像が実際に何をするかはわかりませんが、両方のシナリオを処理したいと考えています。[知っていれば、この状況をより適切にターゲットにできたかもしれません]
シナリオ 2 を処理するために、上記のパス拡張チェックを追加しただけで、すべてがスムーズに処理されます。ところで、ターゲット ディレクトリには .png 画像しかありません。
シナリオ 1 の場合、.png ファイルに対する外部要求は通過しますが、ファイルは実際には .jpg としてエンコードされており、それが問題の部分です。拡張子を書き直せばいいのに。Response.Redirect を使用してそれを実行しようとしましたが、Application_Start 内で作業しているため、アクセスできません。