This article is currently in the process of being translated into Japanese (~94% done).
The Image control
WPFのImageコントロールはアプリケーションにイメージを表示します。これは非常に多用途のコントロールで、これからこの記事で学ぶように、使いやすいオプションとメソッドを備えています。しかし、まず、ウィンドウにイメージを表示する最も基本的な例を見てみましょう。
<Image Source="https://upload.wikimedia.org/wikipedia/commons/3/30/Googlelogo.png" />
結果はこのようになります。
例の中で使っているSourceプロパティは表示するイメージを指定し、おそらくこのコントロールで一番重要なプロパティです。その点を掘り下げてみましょう。
Sourceプロパティ
最初の例を見ればわかるように、Sourceプロパティはイメージコントロールに表示するイメージを簡易に指定出来ます。この例ではリモートイメージを使っています。イメージコントロールはイメージを自動的に取得し、表示できるようになったらすぐに表示します。これは、イメージコントロールがいかに多用途かを示す良い例です。しかし多くの場合、イメージをリモートからロードするよりもアプリケーションにバンドルしたいと思うでしょう。これも簡単にできます!
知っているとは思いますが、プロジェクトにはリソースファイルを追加できます。それはVisual Studio プロジェクトの内部に保存でき、他のWPF関連ファイル(ウインドウやユーザーコントロールなど)と同じようにSolution Explorerに表示されます。リソースの代表例はイメージで、これを取り込むためには関連するフォルダをプロジェクトにコピーするだけです。そうするとアプリケーションに組み込まれ(特別にVisual Studioに教えなくても)、リソースのURLフォーマットを使ってアクセスすることが出来ます。もし"Images"フォルダに"google.png"というイメージファイルがある場合、以下のように書けます。
<Image Source="/WpfTutorialSamples;component/Images/google.png" />
これらのURIはしばしば "Pack URI's"と呼ばれ、たくさんの細部を持つ重いトピックですが、今のところは二つの重要な部分から成っていることに注意して下さい。
- 最初の部分(/WpfTutorialSamples;component),はアセンブリ名(アプリケーション名WpfTutorialSamples) でキーワード"component"と組み合わされています。
- 2つ目は指定されたリソースの相対パスです。/Images/google.png
この書き方を使って、アプリケーションに取りう込まれたリソースを簡単に参照できます。また参照先を指定するためWPF フレームワークは単純な相対URLも受け入れるとします。これはアプリケーションでリソースに関してよほど複雑なことをしない限り、これで十分です。単純な相対URLを使うと、このようになります。
<Image Source="/Images/google.png" />
動的なイメージのロード(コードビハインド)
多くの場合、XAMLで直接イメージソースを指定して問題ないですが、動的にイメージをロードする必要もあります。例えばユーザーが選ぶ場合など。これはコードビハインドから行います。ここでは、ユーザーのコンピュータの中でOpenFileDialogを使って選んだイメージをどのようにロードするか示します。
private void BtnLoadFromFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if(openFileDialog.ShowDialog() == true)
{
Uri fileUri = new Uri(openFileDialog.FileName);
imgDynamic.Source = new BitmapImage(fileUri);
}
}
ダイアログで選んだパスのUriオブジェクトを渡してBitmapImageインスタンスを作っていることに注意して下さい。これと全く同じテクニックを使ってアプリケーションのリソースとして格納されているイメージをロードすることが出来ます。
private void BtnLoadFromResource_Click(object sender, RoutedEventArgs e)
{
Uri resourceUri = new Uri("/Images/white_bengal_tiger.jpg", UriKind.Relative);
imgDynamic.Source = new BitmapImage(resourceUri);
}
ここでは以前の例の一つで使ったのと同じ相対パスを使っています。ただ、Uriインスタンスを作るときにUriKind.Relativeを渡すのを忘れないで下さい。これで、渡したパスが絶対パスではないことを伝えます。以下にコードビハインドのXAMLのソースとスクリーンショットを示します。
<Window x:Class="WpfTutorialSamples.Basic_controls.ImageControlCodeBehindSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTutorialSamples.Basic_controls"
mc:Ignorable="d"
Title="ImageControlCodeBehindSample" Height="300" Width="400">
<StackPanel>
<WrapPanel Margin="10" HorizontalAlignment="Center">
<Button Name="btnLoadFromFile" Margin="0,0,20,0" Click="BtnLoadFromFile_Click">Load from File...</Button>
<Button Name="btnLoadFromResource" Click="BtnLoadFromResource_Click">Load from Resource</Button>
</WrapPanel>
<Image Name="imgDynamic" Margin="10" />
</StackPanel>
</Window>
Stretchプロパティ
明らかに重要なSourceプロパティの次にイメージコントロールで興味深いプロパティはStretchかもしれません。 これはImageコントロールと大きさが異なるイメージがロードされた時どのように振る舞うかを制御します。 完全に静的なレイアウトでない限りウインドウのサイズはユーザーが変えられるので、変化はいつでも起こります。 つまり、Imageコントロールの大きさも変わります。
次の例を見ればわかるように、Stretchプロパティはイメージの表示に大きな違いをもたらします。
<Window x:Class="WpfTutorialSamples.Basic_controls.ImageControlStretchSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTutorialSamples.Basic_controls"
mc:Ignorable="d"
Title="ImageControlStretchSample" Height="450" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Column="0" HorizontalAlignment="Center" FontWeight="Bold">Uniform</Label>
<Label Grid.Column="1" HorizontalAlignment="Center" FontWeight="Bold">UniformToFill</Label>
<Label Grid.Column="2" HorizontalAlignment="Center" FontWeight="Bold">Fill</Label>
<Label Grid.Column="3" HorizontalAlignment="Center" FontWeight="Bold">None</Label>
<Image Source="/Images/white_bengal_tiger.jpg" Stretch="Uniform" Grid.Column="0" Grid.Row="1" Margin="5" />
<Image Source="/Images/white_bengal_tiger.jpg" Stretch="UniformToFill" Grid.Column="1" Grid.Row="1" Margin="5" />
<Image Source="/Images/white_bengal_tiger.jpg" Stretch="Fill" Grid.Column="2" Grid.Row="1" Margin="5" />
<Image Source="/Images/white_bengal_tiger.jpg" Stretch="None" Grid.Column="3" Grid.Row="1" Margin="5" />
</Grid>
</Window>
分かりにくいかもしれませんが、4つのイメージコントロールは異なるStretchプロパティで同じ画像を表示しています。これらのモードの動作は次のとおりです。
- Uniform: デフォルトです。イメージコントロール内に合うように拡大縮小されます。 画像の アスペクト比 は保たれます。
- UniformToFill: イメージコントロール全体に表示されるように拡大縮小されます。アスペクト比は保たれます。
- Fill: イメージコントロールに合うように拡大縮小されます。アスペクト比は保たれません。高さと幅はそれぞれ個別にスケーリングされます。
- None: イメージコントロールより画像が小さい場合は何も起こりません。逆に大きい場合はイメージコントロールに合うように単純に切り取られます。すなわち画像の一部分だけが表示されます。
まとめ
WPFの Image コントロールを使えば、この記事でデモしたように、リモートソースや埋め込まれたリソースやローカルコンピュータ等の画像を簡単に表示出来るようになります。