作成者: Fabio Yeon
これは、提供されるイメージにユーザー構成の透かしを動的に挿入するネイティブ (C++) モジュールを記述する方法と、新しいモジュールを簡単に管理できるように構成と inetmgr UI ツールを拡張する方法のサンプルです。
透かしモジュールには、次の機能があります。
- 任意の構成レベル (つまりサイト、アプリケーション、仮想ディレクトリなど) で有効または無効にできます。
- JPG、GIF、PNG の画像形式に透かしを付けることができます。
- 透かし画像には、JPG、GIF、または PNG 形式を使用できます。 透かし画像は、透かしが付けられる画像と同じ種類である必要はありません (つまり、GIF 透かし画像を使用して、PNG 画像要求に透かしを適用できます)。
- 透かし画像の場所 ("左上"、"右上"、"左下"、"右下"、"中央"、"タイル" と "ストレッチ" の各オプション) を構成できます。 "ストレッチ" オプションのみが、必要に応じて透かし画像を変更または修正します。
- 透かし画像の透明度レベルを 0 から 100% まで選択することもできます。
サンプルをコンパイルするには、Windows Vista または Windows Server 2008 用のプラットフォーム SDK をインストールする必要があります。 サンプルに含まれるプロジェクト ファイルは、Visual Studio 2005 または 2008 で読み込むことができます。
これらのサンプルのソース コードは、ここで入手できます。
透かしモジュール
このサンプルの最初のコンポーネントは、透かしモジュール自体です。 これは、要求が処理されるのを監視するネイティブ C++ モジュールであり、要求の MIME の種類が画像であることを示している場合は、ユーザーが構成した透かしを画像に動的に適用し、送信イメージを置き換えます。 これはすべて、要求ハンドラーの後で実行されるモジュールで透過的に行われます。 この図を次に示します。
- このコードのロジックは非常に簡単です。
- モジュールが最初に読み込まれると、RQ_EXECUTE_REQUEST_HANDLER 後イベントに登録されます。これは、要求ハンドラーの実行直後に通知を受け取る必要があることをシステムに示します。
- これで、RQ_EXECUTE_REQUEST_HANDLER 後のイベントが発生すると、そのパスの構成が取得されます。 有効になっていない場合、要求と保釈に対してそれ以上何も行われません。
- 有効になっている場合は、"Content-Type" 応答ヘッダーを確認し、それが画像の種類であるかどうかを確認します。 そうでない場合は、保釈されます。
- 画像の場合、応答がバッファーかファイル ハンドルかを確認します。 後の場合は、イメージをメモリに読み込み、ユーザーが構成した設定 (つまり画像ファイル、位置、透明度) に基づいて透かしを適用し、結果の画像をメモリ内バッファーに保存し、応答データをメモリ内バッファーに置き換えて返します。
- メモリ内バッファーは、モジュールの "Dispose" メソッドで解放されます。
ATL の CImage クラスを使用すると、特にさまざまな画像形式を簡単に操作できるため、イメージの読み込みと処理が非常に簡単になります。
ここで、このサンプルにはいくつかの注意事項があり、特に "実際の" 運用環境で使用する場合は考慮する必要があります。
- このコードは、応答がファイル ハンドル内にあるイメージの種類に対してのみ機能します。 HTTP_RESPONSE オブジェクトは、代わりに一連のバッファーにイメージを格納する場合があります。 興味深い演習は、応答オブジェクト内のバッファーをラップするメモリ内 IStream 実装を作成することです (複数のバッファー応答に注意してください)。
- モジュールは、"ETag" 応答ヘッダーを変更または更新しません。 つまり、結果として得られる透かし付きイメージは、クライアントからは "実際の" イメージと見なされますが、クライアントのキャッシュ ロジックにおいては混同される可能性もあります。 これを正しく実装するには、透かし付き画像の構成を考慮に入れて "ETag" を変更する必要があります。 たとえば、現在の実装では、透明度が "50%" の "UpperLeft" 位置に "WatermarkFileA" の画像に透かしを付け、ブラウザー (つまり Internet Explorer) で要求を行った場合、IE はさまざまな応答ヘッダーに基づいてそのイメージをキャッシュします。 透かしモジュールの構成を変更し (つまり、イメージ、位置、または透明度を変更)、F5 キーを介してファイルをもう一度要求した場合、イメージは IE にキャッシュされているため、IE はイメージを要求せず、単に "HEAD" 要求を実行し、イメージに関して持っている情報を送信します。 イメージが変更されたことを要求ハンドラーは認識していないため、先ほど送信した応答がまだ有効であると応答し、要求処理を終了します。 残念ながら、この場合、透かしモジュールは新しい構成でイメージを実行して透かしを更新する機会がないため、クライアントは以前の透かし付き画像を表示し続けます。 これに対する適切な修正では、透かしモジュールが応答の "ETag" にその構成を何らかの方法で組み込むことで、イメージまたは透かしモジュールに加えられた変更が起点となって、クライアントでキャッシュされたイメージが無効化され、再処理されるようにします。
構成
透かしモジュールの構成は、"system.webServer" 名前空間の新しいセクションを使用して行われます。 スキーマ ファイルは次のとおりです。
<configSchema>
<sectionSchema name="system.webServer/watermark">
<attribute name="enabled" type="bool" defaultValue="false" />
<attribute name="watermarkImage" type="string" />
<attribute name="transparency" type="uint" defaultValue="50" validationType="integerRange" validationParameter="0,100" />
<attribute name="position" type="enum" defaultValue="LowerRight" >
<enum name="UpperLeft" value="0" />
<enum name="UpperRight" value="1" />
<enum name="LowerLeft" value="2" />
<enum name="LowerRight" value="3" />
<enum name="Center" value="4" />
<enum name="Stretch" value="5" />
<enum name="Tile" value="6" />
</attribute>
</sectionSchema>
</configSchema>
ファイル "watermark.xml" は、"system.webServer" 名前空間の下の "applicationhost.config" ファイルにセクション定義を追加して有効にするために、%windir%\system32\inetsrv\config\schema
ディレクトリにドロップする必要があります。
<section name="Watermark" overrideModeDefault="Allow" />
モジュールを使用するには、グローバル モジュール一覧 "system.webServer\globalModules" にモジュールをインストールする必要があります。
<add name="WatermarkModule" image="c:\Watermark\Watermark.dll" />
アプリケーションのモジュール一覧 "system.webServer\modules" にもインストールします。
<add name="WatermarkModule" />
Inetmgr
これは、モジュール サンプルと共に、新しい "Inetmgr" UI 管理ツールへの管理プラグインであるマネージド クラスのセットです。 新しい "Inetmgr" を記述および拡張する方法については、他にもさまざまなドキュメントがあります。このドキュメントはここで入手できます。 つまり、それらを使用するには、ビルドし、DLL を GAC (グローバル アセンブリ キャッシュ) に追加し、次の構成を %windir%\system32\inetsrv\config\administration.config
ファイルに追加する必要があります。
<moduleProviders> コレクションに、次のエントリを追加します。
<add name="Watermark" type="WatermarkServer.WatermarkModuleProvider, Watermarkserver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5f6f8f3f74d67fe4" />
また、次の行を <modules>
コレクションに追加します。
<add name="Watermark" />
ツールを再起動すると、サイトで新しいアイコンを使用できるようになります。