Xamarin.Formsアプリに埋め込まれた画像リソースを表示するには、ImageSourceクラスのFromResource/FromStreamメソッドが使える。
対象:Visual Studio 2015以降
Xamarin.Formsは、XAMLとC#を使ってAndroid/iOS/Windows向けのクロスプラットフォーム開発を行える開発環境だ。
本稿では、Xamarin.Formsアプリで、アプリに埋め込んだリソースから画像を取得して表示する方法を解説する。
「リソースID」(後述)を指定して、ImageSourceクラス(Xamarin.Forms名前空間)のFromResourceメソッドを呼び出すとImageSourceオブジェクトが得られる。それをImageコントロール(Xamarin.Forms名前空間)のSourceプロパティにセットすればよい。
リソースIDは、アセンブリ名(=既定ではプロジェクト名)と、プロジェクト内の画像ファイルのパスとを、「.」でつないだ文字列である。また、画像ファイルの[ビルド アクション]は[埋め込みリソース]と指定してビルドする必要がある。
ImageSourceクラスのFromResourceメソッドを使って埋め込みリソースの画像を表示するコードは次のようになる。
// XAMLコード側には、「Image1」という名前のImageコントロールが配置してある
// 表示したい埋め込み画像のリソースID
string resourceID = "……省略……";
// 画像ファイルの[ビルドアクション]は[埋め込みリソース]にしておく
// ImageSourceクラスのFromResourceメソッドを使う
Image1.Source = ImageSource.FromResource(resourceID);
別の方法として、リフレクションを使って埋め込みリソースを取り出すこともできる。
リフレクションによって目的の画像リソースのストリームを取得し、それをImageSourceクラスのFromStreamメソッドに渡せばよい(次のコード)。
// XAMLコード側には、「Image2」という名前のImageコントロールが配置してある
// 表示したい埋め込み画像のリソースID
string resourceID = "……省略……";
// 画像ファイルの[ビルドアクション]は[埋め込みリソース]にしておく
// ImageSourceクラスのFromStreamメソッドを使う
Image2.Source = ImageSource.FromStream(() =>
// このコードが含まれるアセンブリから画像リソースをストリームとして取り出す
// (コード冒頭部に「using System.Reflection;」が必要)
GetType().GetTypeInfo().Assembly.GetManifestResourceStream(resourceID)
);
URIやファイル名を指定して画像を表示する場合と同じようにリソースIDを指定できる「ResourceImageSource」クラスのようなものがあればXAMLコードで記述できるのだが、残念ながら用意されていない。
ないのなら、作ってしまおう。
IMarkupExtensionインタフェース(Xamarin.Forms.Xaml名前空間)を実装して、次のコードのようなXAMLマークアップ拡張を作る。
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace dotNetTips1161
{
[ContentProperty("Source")]
public class ImageResourceExtension : IMarkupExtension
{
// XAMLコードで設定する属性(今回はクラスにContentProperty属性も指定する)
public string Source { get; set; }
// IMarkupExtensionインタフェースの実装
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Source == null) return null;
return ImageSource.FromResource(Source);
}
}
}
上で作ったImageResourceExtensionクラスを使えば、XAMLコードでリソースIDを指定して画像を表示できる(次のコード)。
<Image Source="{local:ImageResource
Source=……リソースID省略……}" />
<!-- リソースID手前の「Source=」は省略可能 -->
実際の例として、以上で説明したコードを試してみよう。
あらかじめ、表示に使う適当な画像ファイルを用意しておいてほしい。以下ではファイル名は「SamplePhoto01.png」としている。
ソリューションを新しく作るときに[Blank Xaml App (Xamarin.Forms Portable)]を選ぶ。以下ではソリューション名(=PCLプロジェクトの名前)は「dotNetTips1161」としている。
そのPCLプロジェクトに、「Images」というフォルダーを作り、用意しておいた画像を置き、プロパティの[ビルド アクション]を[埋め込みリソース]にする(次の画像)。
画像ファイルのリソースIDは次のようになる。
次に、PCLプロジェクトに新しくクラスのファイルを追加する。ファイル名は「ImageResourceExtension.cs」とし(上の画像にもある)、内容を前述した「ImageResourceExtension」クラス(=XAMLマークアップ拡張)に書き換える。
そうしたら、PCLプロジェクトにあるMainPage.xamlファイルの内容を次のように変更する。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:dotNetTips1161"
x:Class="dotNetTips1161.MainPage">
<!--<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />-->
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" />
</ContentPage.Padding>
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Image">
<Setter Property="Aspect" Value="AspectFit" />
<Setter Property="HeightRequest" Value="60" />
<Setter Property="VerticalOptions" Value="StartAndExpand" />
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="EndAndExpand" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Label Text="Xamlで表示(ImageResourceExtensionを利用)" />
<Image Source="{local:ImageResource dotNetTips1161.Images.SamplePhoto01.png}" />
<Label Text="コードで表示(ImageSource.FromResource)" />
<Image x:Name="Image1" />
<Label Text="コードで表示(ImageSource.FromStream)" />
<Image x:Name="Image2" />
</StackLayout>
</ContentPage>
次に、コードビハインドのMainPage.xaml.csファイルに次のようなコードを追加する。
public MainPage()
{
InitializeComponent();
// 表示したい埋め込み画像のリソースID
string resourceID = "dotNetTips1161.Images.SamplePhoto01.png";
// ImageSource.FromResourceメソッドを使う
Image1.Source = ImageSource.FromResource(resourceID);
// ImageSource.FromStreamメソッドを使う
Image2.Source = ImageSource.FromStream(() =>
// 冒頭に「using System.Reflection;」が必要
GetType().GetTypeInfo().Assembly
.GetManifestResourceStream(resourceID)
);
}
これで実行してみると、次の画像のようになる。
アプリの埋め込みリソースにある画像をImageコントロールに表示するには、ImageSourceクラスのFromResourceメソッドを使うのが簡単だ。あるいは、同じクラスのFromStreamメソッドを使ってもよい。
XAMLコードで記述するためには、XAMLマークアップ拡張をC#で書く必要がある。
画像ファイルを埋め込みリソースにするには、そのプロパティの[ビルド アクション]を[埋め込みリソース]に変える。忘れないようにしよう。
利用可能バージョン:Visual Studio 2015以降
カテゴリ:Xamarin 処理対象:Xamarin.Forms
関連TIPS:Xamarin.Forms:プロジェクトにXamlページを追加するには?
関連TIPS:Xamarin.Forms:プラットフォームに応じて画面の一部を変えるには?
関連TIPS:Xamarin.Forms:コントロールを等間隔に配置するには?
関連TIPS:Xamarin.Forms:URLを指定して画像を表示するには?
関連TIPS:Xamarin.Forms:ファイルを指定して画像を表示するには?
Copyright© Digital Advantage Corp. All Rights Reserved.