ASP.NET Web ページ (Razor) サイトでの画像の操作
作成者: Tom FitzMacken
この記事では、ASP.NET Web ページ (Razor) Web サイトで画像の追加、表示、操作 (サイズ変更、反転、透かしの追加) を行う方法について説明します。
ここでは、次の内容について学習します。
- ページに画像を動的に追加する方法。
- ユーザーが画像をアップロードできるようにする方法。
- 画像のサイズを変更する方法。
- 画像を反転または回転する方法。
- 透かしを画像に追加する方法。
- 透かしとして画像を使用する方法。
この記事で紹介する ASP.NET プログラミング機能を次に示します。
WebImage
ヘルパー。- パスとファイルの名前を操作できるメソッドを提供する
Path
オブジェクト。チュートリアルで使用するソフトウェアのバージョン
- ASP.NET Web ページ (Razor) 2
- WebMatrix 2
このチュートリアルは、WebMatrix 3 でも動作します。
Web ページに画像を動的に追加する
Web サイトの開発中に、Web サイトや個々のページに画像を追加できます。 また、ユーザーが画像をアップロードできるようにすることもできます。これは、ユーザーによるプロフィール写真の追加などのタスクに役立つ場合があります。
サイトで既に使用可能になっている画像を単にページに表示するには、次のような HTML <img>
要素を使用します。
<img src="images/Photo1.jpg" alt="Sample Photo" />
ただし、画像を動的に表示する (どの画像が表示されるかはページが実行されるまで不明) ことが必要になる場合もあります。
このセクションの手順では、ユーザーが画像名の一覧から画像ファイル名を指定することで、画像をすぐに表示する方法を示します。 ユーザーが、ドロップダウン リストから画像の名前を選択した後、ページを送信すると、選択した画像が表示されます。
WebMatrix で、新しい Web サイトを作成します。
DynamicImage.cshtml という名前の新しいページを追加します。
Web サイトのルート フォルダーに新しいフォルダーを追加し、images という名前を付けます。
作成した images フォルダーに 4 つの画像を追加します。 (手元にあるどの画像でも構いませんが、ページに収まるサイズであることが必要です。)画像を、Photo1.jpg、Photo2.jpg、Photo3.jpg、Photo4.jpg という名前に変更します。 (この手順では Photo4.jpg は使いませんが、この記事の後半で使用します。)
4 つの画像が読み取り専用としてマークされていないことを確認します。
ページ内の既存のコンテンツを次のように置き換えます。
@{ var imagePath= ""; if( Request["photoChoice"] != null){ imagePath = @"images\" + Request["photoChoice"]; } } <!DOCTYPE html> <html> <head> <title>Display Image on the Fly</title> </head> <body> <h1>Displaying an Image On the Fly</h1> <form method="post" action=""> <div> I want to see: <select name="photoChoice"> <option value="Photo1.jpg">Photo 1</option> <option value="Photo2.jpg">Photo 2</option> <option value="Photo3.jpg">Photo 3</option> </select> <input type="submit" value="Submit" /> </div> <div style="padding:10px;"> @if(imagePath != ""){ <img src="@imagePath" alt="Sample Image" width="300px" /> } </div> </form> </body> </html>
ページの本文には、
photoChoice
という名前のドロップダウン リスト (<select>
要素) があります。 リストには 3 つのオプションがあり、各リスト オプションのvalue
属性には、images フォルダーに配置した画像のいずれかの名前があります。 基本的に、リストではユーザーが "Photo 1" のようなフレンドリ名を選択でき、そうすると、ページの送信時に .jpg ファイルの名前が渡されます。コードでは、
Request["photoChoice"]
を読み取ることで、リストからユーザーの選択 (画像ファイル名) を取得できます。 最初に、選択対象があるかどうかを確認します。 ある場合は、画像のフォルダー名とユーザーの画像ファイル名で構成される画像のパスを作成します。 (パスを作成しても、Request["photoChoice"]
に何もないとエラーが発生します。)これにより、次のような相対パスが作成されます。images/Photo1.jpg
パスは、
imagePath
という名前の変数に格納されます。これは後でページに必要になります。本文には、ユーザーが選択した画像を表示するために使用される
<img>
要素もあります。 静的要素を表示する場合と同様に、src
属性はファイル名や URL には設定されません。 代わりに、@imagePath
に設定されます。これは、コードで設定したパスから値を取得することを意味します。ただし、ページを初めて実行する場合は画像が表示されません。ユーザーが何も選択していないためです。 これは通常、
src
属性が空で、画像が赤の "x" (または画像が見つからないときにブラウザーがレンダリングするもの) として表示されることを意味します。 これを防ぐために、imagePath
変数に何かが含まれているかどうかをテストするif
ブロックに<img>
要素を配置します。 ユーザーが選択を行うと、imagePath
にパスが含まれます。 ユーザーが画像を選択しなかった場合、またはこれがページの初回表示である場合、<img>
要素はレンダリングさえされません。ファイルを保存し、ブラウザーでページを実行します。 (実行する前に、ファイル ワークスペース内でこのページが選択されていることを確認してください)。
ドロップダウン リストから画像を選択し、[サンプル画像] をクリックします。 選択内容が異なると、表示される画像も変わることを確認します。
画像をアップロードする
前の例では、画像を動的に表示する方法を示しましたが、これは、画像が Web サイトに既にある場合にのみ機能します。 この手順では、ユーザーが画像をアップロードできるようにし、その画像をページに表示する方法を示します。 ASP.NET では、画像を作成、操作、保存するメソッドを持つ WebImage
ヘルパーを使用して、即座に画像を操作できます。 WebImage
ヘルパーは、.jpg、.png、.bmp など、一般的なすべての Web 画像ファイル タイプをサポートします。 この記事では、.jpg 画像を使用しますが、どのタイプの画像を使用することもできます。
新しいページを追加し、UploadImage.cshtml という名前を付けます。
ページ内の既存のコンテンツを次のように置き換えます。
@{ WebImage photo = null; var newFileName = ""; var imagePath = ""; if(IsPost){ photo = WebImage.GetImageFromRequest(); if(photo != null){ newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName); imagePath = @"images\" + newFileName; photo.Save(@"~\" + imagePath); } } } <!DOCTYPE html> <html> <head> <title>Image Upload</title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> <fieldset> <legend> Upload Image </legend> <label for="Image">Image</label> <input type="file" name="Image" /> <br/> <input type="submit" value="Upload" /> </fieldset> </form> <h1>Uploaded Image</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="image" /> </div> } </body> </html>
テキストの本文には
<input type="file">
要素があり、これによりユーザーはアップロードするファイルを選択できます。 [送信] をクリックすると、選択したファイルがフォームと共に送信されます。アップロードされた画像を取得するには、
WebImage
ヘルパーを使用します。これには、画像を操作するための便利なメソッドがすべて含まれています。 具体的には、WebImage.GetImageFromRequest
を使用すると、アップロードされた画像 (ある場合) を取得し、それをphoto
という名前の変数に格納できます。この例の多くの作業には、ファイル名とパス名の取得と設定が伴います。 問題は、ユーザーがアップロードした画像の名前 (名前のみ) を取得して、その画像の格納先とする新しいパスを作成することが必要になることです。 ユーザーは同じ名前の画像を複数アップロードする可能性があるため、一意の名前を作成するわずかな追加コードを使用して、ユーザーが既存の画像を上書きしないようにします。
画像が実際にアップロードされている場合 (テスト
if (photo != null)
)、画像のFileName
プロパティから画像名を取得します。 ユーザーが画像をアップロードすると、FileName
には、ユーザーの元の名前 (ユーザーのコンピューターからのパスを含む) が含まれます。 次のようになります。C:\Users\Joe\Pictures\SamplePhoto1.jpg
ただし、すべてのパス情報は必要ありません。必要なのは、実際のファイル名 (SamplePhoto1.jpg) のみです。
Path.GetFileName
メソッドを次のように使用して、パスからファイルだけを取り出すことができます。Path.GetFileName(photo.FileName)
次に、元の名前に GUID を追加して、新しい一意のファイル名を作成します。 (GUID の詳細については、この記事の後半にある「GUID について」を参照してください。)次に、画像の保存に使用できる完全なパスを作成します。 保存パスは、新しいファイル名、フォルダー (images)、現在の Web サイトの場所で構成されます。
Note
コードによって、images フォルダーにファイルが保存されるようにするには、そのフォルダーに対する読み取り/書き込み権限がアプリケーションに必要です。 開発用コンピューターでは、これは通常問題ではありません。 ただし、ホスティング プロバイダーの Web サーバーにサイトを発行する場合は、それらのアクセス許可を明示的に設定することが必要になる場合があります。 ホスティング プロバイダーのサーバーでこのコードを実行し、エラーが発生した場合は、ホスティング プロバイダーに問い合わせて、それらのアクセス許可を設定する方法を確認してください。
最後に、
Save
ヘルパーのWebImage
メソッドに保存パスを渡します。 これにより、アップロードされた画像が新しい名前の下に格納されます。 save メソッドは次のようになります:photo.Save(@"~\" + imagePath)
。 完全なパスが@"~\"
に追加されます。これは現在の Web サイトの場所です。 (~
演算子の詳細については、「Razor 構文を使用した ASP.NET Web プログラミングの概要」を参照してください。)前の例と同様に、ページの本文には画像を表示する
<img>
要素が含まれています。imagePath
が設定されている場合、<img>
要素がレンダリングされ、そのsrc
属性がimagePath
値に設定されます。ブラウザーでページを実行します。
画像をアップロードし、ページに表示されていることを確認します。
サイトで、images フォルダーを開きます。 新しいファイルが次のようなファイル名で追加されていることがわかります。
45ea4527-7ddd-4965-b9ca-c6444982b342_MyPhoto.png
これは、ファイル名の先頭に GUID が付いた、アップロード後の画像です。 (実際のファイルには別の GUID が付き、おそらくは MyPhoto.png ではない名前になります。)
ヒント
GUID について
GUID (グローバルに一意の ID) は、通常、次のような形式でレンダリングされる識別子です: 936DA01F-9ABD-4d9d-80C7-02AF85C822A8
。 数字と文字 (A から F) は GUID ごとに異なりますが、8-4-4-4-12 文字のグループを使用するパターンであることは同じです。 (厳密には、GUID は 16 バイト/128 ビットの数字です。)GUID が必要な場合は、GUID を生成する特殊なコードを呼び出すことができます。 GUID の背後にあるのは、膨大なサイズの数値 (3.4 x 1038) とそれを生成するためのアルゴリズムの間で、結果の数値が実質的にいずれかの種類であることを保証するという考え方です。 そのため、同じ名前を 2 回使用しないことを保証する必要がある場合、GUID は名前を生成するのに適した方法です。 欠点は GUID がユーザー フレンドリでないということで、コードでしか使われない名前に使用される傾向があります。
イメージのサイズ変更
ユーザーからの画像を受け付ける Web サイトの場合は、画像を表示または保存する前にサイズを変更することをお勧めします。 この場合も WebImage
ヘルパーを使用できます。
この手順では、アップロードした画像のサイズを変更してサムネイルを作成し、サムネイルと元の画像を Web サイトに保存する方法を示します。 ページにサムネイルを表示し、ハイパーリンクを使用してユーザーをフルサイズの画像にリダイレクトします。
Thumbnail.cshtml という名前の新しいページを追加します。
images フォルダーに、thumbs という名前のサブフォルダーを作成します。
ページ内の既存のコンテンツを次のように置き換えます。
@{ WebImage photo = null; var newFileName = ""; var imagePath = ""; var imageThumbPath = ""; if(IsPost){ photo = WebImage.GetImageFromRequest(); if(photo != null){ newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName); imagePath = @"images\" + newFileName; photo.Save(@"~\" + imagePath); imageThumbPath = @"images\thumbs\" + newFileName; photo.Resize(width: 60, height: 60, preserveAspectRatio: true, preventEnlarge: true); photo.Save(@"~\" + imageThumbPath); } } } <!DOCTYPE html> <html> <head> <title>Resizing Image</title> </head> <body> <h1>Thumbnail Image</h1> <form action="" method="post" enctype="multipart/form-data"> <fieldset> <legend> Creating Thumbnail Image </legend> <label for="Image">Image</label> <input type="file" name="Image" /> <br/> <input type="submit" value="Submit" /> </fieldset> </form> @if(imagePath != ""){ <div class="result"> <img src="@imageThumbPath" alt="Thumbnail image" /> <a href="@Html.AttributeEncode(imagePath)" target="_Self"> View full size </a> </div> } </body> </html>
このコードは、前の例のコードに似ています。 違いは、このコードは画像を 2 回保存する (通常の 1 回と、画像のサムネイル コピーを作成した後の 1 回) という点です。 まず、アップロードした画像を取得し、images フォルダーに保存します。 次に、サムネイル画像の新しいパスを作成します。 サムネイルを実際に作成するには、
WebImage
ヘルパーのResize
メソッドを呼び出して、60 ピクセル x 60 ピクセルの画像を作成します。 この例では、縦横比を維持する方法と、画像が拡大されないようにする方法 (新しいサイズにしたときに画像が実際に大きくなってしまう場合に備えるため) を示します。 サイズ変更された画像は、thumbs サブフォルダーに保存されます。マークアップの最後で、前の例で見た動的な
<img>
属性と同じsrc
要素を使用して、画像を条件付きで表示します。 この場合は、サムネイルを表示します。 また、<a>
要素を使用して、画像の大型バージョンへのハイパーリンクを作成します。<img>
要素のsrc
属性と同様に、<a>
要素のhref
属性をimagePath
にあるものに動的に設定します。 パスが URL として機能することを確認するには、imagePath
をHtml.AttributeEncode
メソッドに渡します。これにより、パス内の予約文字が、URL 内で問題のない文字に変換されます。ブラウザーでページを実行します。
写真をアップロードし、サムネイルが表示されていることを確認します。
サムネイルをクリックすると、フルサイズの画像が表示されます。
images と images/thumbs に新しいファイルが追加されていることに注目してください。
画像を回転および反転する
WebImage
ヘルパーを使用して、画像を反転または回転することもできます。 この手順では、サーバーから画像を取得し、画像を上下に反転して保存し、反転した画像をページに表示する方法を示します。 この例では、サーバーに既にあるファイル (Photo2.jpg) を使用します。 実際のアプリケーションでは、前の例で行ったように、動的に表示された名前の画像を反転する場合があります。
FlipImage.cshtml という名前の新しいページを追加します。
ページ内の既存のコンテンツを次のように置き換えます。
@{ var imagePath= ""; WebImage photo = new WebImage(@"~\Images\Photo2.jpg"); if(photo != null){ imagePath = @"images\Photo2.jpg"; photo.FlipVertical(); photo.Save(@"~\" + imagePath); } } <!DOCTYPE html> <html> <head> <title>Get Image From File</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Flip Image Vertically</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="Image" /> </div> } </body> </html>
このコードは、
WebImage
ヘルパーを使用してサーバーから画像を取得します。 画像ヘのパスは、画像を保存するために前の例で使用したのと同じ手法を使用して作成し、WebImage
を使用して画像を作成するときにそのパスを渡します。WebImage photo = new WebImage(@"~\Images\Photo2.jpg");
画像が見つかった場合は、前の例と同様に、新しいパスとファイル名を作成します。 画像を反転するには、
FlipVertical
メソッドを呼び出して、画像をもう一度保存します。src
属性をimagePath
に設定した<img>
要素を使用することで、画像がページに再び表示されます。ブラウザーでページを実行します。 Photo2.jpg の画像が逆さまに表示されます。
ページを更新するか、ページをもう一度要求して、画像が再び正しい向きに反転していることを確認します。
画像を回転する場合も同じコードを使用しますが、FlipVertical
または FlipHorizontal
を呼び出すのではなく、RotateLeft
または RotateRight
を呼び出します。
透かしを画像に追加する
Web サイトに画像を追加する場合は、保存するかページに表示する前に、透かしを画像に追加できます。 透かしがよく使用されるのは、画像に著作権情報を追加したり、企業名を宣伝する場合です。
Watermark.cshtml という名前の新しいページを追加します。
ページ内の既存のコンテンツを次のように置き換えます。
@{ var imagePath= ""; WebImage photo = new WebImage(@"~\Images\Photo3.jpg"); if(photo != null){ imagePath = @"images\Photo3.jpg"; photo.AddTextWatermark("My Watermark", fontColor:"Yellow", fontFamily: "Arial"); photo.Save(@"~\" + imagePath); } } <!DOCTYPE html> <html> <head> <title>Water Mark</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Adding a Watermark to an Image</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="Image" /> </div> } </body> </html>
このコードは、前の FlipImage.cshtml ページのコードに似ています (ただし、今回は Photo3.jpg ファイルを使用)。 透かしを追加するには、画像を保存する前に
WebImage
ヘルパーのAddTextWatermark
メソッドを呼び出します。AddTextWatermark
の呼び出しで、"My Watermark" というテキストを渡し、フォントの色を黄色に設定し、フォント ファミリを Arial に設定します。 (ここでは示しませんが、WebImage
ヘルパーを使用すると、不透明度、フォント ファミリ、フォント サイズ、透かしテキストの位置を指定することもできます。)画像を保存するときは、読み取り専用にしないでください。前に見たように、src 属性が
@imagePath
に設定された<img>
要素を使用して、画像がページに表示されます。ブラウザーでページを実行します。 画像の右下隅にある "My Watermark" というテキストに注目してください。
画像を透かしとして使用する
透かしには、テキストを使用する代わりに別の画像を使用できます。 会社のロゴなどの画像を透かしとして使用したり、テキストの代わりに著作権情報の透かし画像を使用することもできます。
ImageWatermark.cshtml という名前の新しいページを追加します。
ロゴとして使用できる画像を images フォルダーに追加し、その画像の名前を MyCompanyLogo.jpg に変更します。 この画像は、幅 80 ピクセル、高さ 20 ピクセルに設定されていれば、はっきり見える画像になっているはずです。
ページ内の既存のコンテンツを次のように置き換えます。
@{ var imagePath = ""; WebImage WatermarkPhoto = new WebImage(@"~\" + @"\Images\MyCompanyLogo.jpg"); WebImage photo = new WebImage(@"~\Images\Photo4.jpg"); if(photo != null){ imagePath = @"images\Photo4.jpg"; photo.AddImageWatermark(WatermarkPhoto, width: 80, height: 20, horizontalAlign:"Center", verticalAlign:"Bottom", opacity:100, padding:10); photo.Save(@"~\" + imagePath); } } <!DOCTYPE html> <html> <head> <title>Image Watermark</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h1>Using an Image as a Watermark</h1> @if(imagePath != ""){ <div class="result"> <img src="@imagePath" alt="Image" /> </div> } </body> </html>
これは、前の例のコードのもう 1 つのバリエーションです。 この場合は、画像を保存する前に、
AddImageWatermark
を呼び出して、透かし画像をターゲット画像 (Photo3.jpg) に追加します。AddImageWatermark
を呼び出すときは、幅を 80 ピクセル、高さを 20 ピクセルに設定します。 MyCompanyLogo.jpg の画像は、ターゲット画像に対し、水平方向には中央揃え、垂直方向には下揃えで配置されます。 不透明度は 100% に設定され、パディングは 10 ピクセルに設定されます。 透かしの画像がターゲット画像よりも大きい場合、何も起こりません。 透かしの画像がターゲット画像よりも大きく、画像の透かしのパディングをゼロに設定した場合、透かしは無視されます。前と同様に、
<img>
要素と動的なsrc
属性を使用して画像を表示します。ブラウザーでページを実行します。 透かしの画像がメイン画像の下部に表示されます。