Xamarin.Forms での画像

イメージは、プラットフォームをまたいで Xamarin.Forms と共有したり、プラットフォームごとに読み込んだり、表示用にダウンロードしたりできます。

画像は、アプリケーションのナビゲーション、使いやすさ、およびブランディングにおける重要な要素です。 Xamarin.Forms アプリケーションは、すべてのプラットフォーム間で画像を共有できる必要があり、さらに各プラットフォームでは、異なる画像を表示する可能性もあります。

プラットフォーム固有の画像は、アイコンやスプラッシュ スクリーンにも必要です。これらはプラットフォームごとに構成する必要があります。

画像を表示する

Xamarin.Forms では、ページに画像を表示するために Image ビューを使用します。 これには、次のように、重要なプロパティがいくつかあります。

  • Source - 画像を表示用に設定する ImageSource インスタンス (ファイル、URI、またはリソースのいずれか)。
  • Aspect - 表示される境界内で画像のサイズを設定する方法 (拡大、トリミング、レターボックスのいずれか)。

ImageSource インスタンスは、画像ソースの種類ごとに、静的メソッドを使用して取得できます。

  • FromFile - 各プラットフォームで解決できるファイル名またはファイルパスを使用します。
  • FromUri - URI オブジェクトを使用します (例: new Uri("http://server.com/image.jpg") $
  • FromResource - Build Action:EmbeddedResource を使用してアプリケーションまたは .NET Standard ライブラリ プロジェクトに埋め込まれた、画像ファイルへのリソース識別子を使用します。
  • FromStream - 画像データを提供するストリームを使用します。

Aspect プロパティは、表示領域に合わせて画像を拡大縮小する方法を決定します。

  • Fill - 表示領域を完全に満たすように画像を拡大します。 これにより、画像の歪みが発生する可能性があります。
  • AspectFill - 表示領域を満たすように、縦横比を維持したまま (つまり歪みなしで) 画像をクリップします。
  • AspectFit - 必要に応じて、画像が表示領域に収まるように画像をレターボックス化し、画像が横長か縦長かに応じて上下または左右に空白スペースを追加します。

画像は、ローカル ファイル埋め込みリソースダウンロードから読み込むか、ストリームから読み込むことができます。 さらに、FontImageSource オブジェクト内でフォント アイコン データを指定することで、Image ビューによりフォント アイコンを表示できます。 詳細については、「フォント ガイド」の「フォント アイコンを表示する」を参照してください。

ローカル画像

画像ファイルは、各アプリケーション プロジェクトに追加し、Xamarin.Forms の共有コードから 参照できます。 このイメージ配布方法は、イメージがプラットフォーム固有の場合に必要になります。例えば、異なるプラットフォームで異なる解像度を使用する場合や、わずかに異なるデザインを使用する場合などです。

すべてのアプリで同一の画像を使用するには、各プラットフォームで同じファイル名を使用する必要があります。また、ファイル名は有効な Android リソース名である必要があります (使用できるのは小文字の英字、数字、アンダースコア、およびピリオドのみ)。

  • iOS - iOS 9 以降で画像を管理およびサポートする方法としては、Asset Catalog Image Set の使用が推奨されています。これには、アプリケーション用に各種のデバイスとスケール ファクターをサポートするのに必要なすべてのバージョンの画像を含む必要があります。 詳細については、「Asset Catalog Image Set への画像の追加」を参照してください。
  • Android - Build Action: AndroidResource を使用して Resources/drawable ディレクトリにイメージを配置します。 DPI が高低両方の画像バージョンを、(drawable-ldpidrawable-hdpidrawable-xhdpi などの適切な名前が付けられた、Resources のサブディレクトリ内に) 提供することができます。
  • ユニバーサル Windows プラットフォーム (UWP) - 既定で画像は、Build Action: Content を使用してアプリケーションのルート ディレクトリに配置されます。 または、画像を別のディレクトリに配置することも可能で、この際には、プラットフォームで個別に指定します。 詳細については、「Windows の既定の画像ディレクトリ」を参照してください。

重要

iOS 9 より前では、通常、 Build Action: BundleResource を使用して、Resources フォルダーに画像が配置されていました。 しかし、iOS アプリで画像を操作するこの方法は、Apple により非推奨となっています。 詳細については、「画像のサイズとファイル名」を参照してください。

ファイルの名前付けと配置に関するこれらの規則に従うことで、次の XAML が、すべてのプラットフォームでイメージを読み込んで表示できるようになります。

<Image Source="waterfront.jpg" />

これと同等の C# コードを次に示します。

var image = new Image { Source = "waterfront.jpg" };

次のスクリーンショットで、各プラットフォームにおける、ローカル画像の表示結果を示します。

ローカル画像を表示するサンプル アプリケーション

Device.RuntimePlatform プロパティを使用すると、次のコード例に示すように、一部またはすべてのプラットフォームで異なる画像ファイルまたはパスを選択でき、柔軟性をより高められます。

image.Source = Device.RuntimePlatform == Device.Android
                ? ImageSource.FromFile("waterfront.jpg")
                : ImageSource.FromFile("Images/waterfront.jpg");

重要

すべてのプラットフォームで同じ画像ファイル名を使用するには、すべてのプラットフォームで、その名前が有効である必要があります。 Android ドローアブルには、名前付けに使用できるのが小文字の英字、数字、アンダースコア、ピリオドのみという制限があり、クロスプラットフォームの互換性のために、他のすべてのプラットフォームでもこれに従う必要があります。 例として、ファイル名 waterfront.png は前出の規則に従っています。一方、無効なファイル名の例には、"water front.png"、"WaterFront.png"、"water-front.png"、"wåterfront.png" などがあります。

ネイティブな解像度 (Retina と高 DPI)

iOS、Android、および UWP は、さまざまな画像解像度をサポートしています。この場合、オペレーティング システムが、デバイスの機能に基づいて実行時に適切な画像を選択します。 Xamarin.Forms はプラットフォームのネイティブな API を使用してローカルの画像を読み込むため、ファイルが適切に名前が付けされておりプロジェクト内に配置されているのであれば、代替の解像度が自動的にサポートされます。

iOS 9 以降で画像を管理する方法としては、適切な Asset Catalog Image Set で要求される各解像度で、画像をドラッグすることが推奨されています。 詳細については、「Asset Catalog Image Set への画像の追加」を参照してください。

iOS 9 より前では、画像の Retina バージョンを Resources フォルダーに配置し、ファイル拡張子の前で、ファイル名の末尾に @2x または @3x 付加すると、解像度を 2 倍あるいは 3 倍にできました (例、myimage@2x.png)。 しかし、iOS アプリで画像を操作するこの方法は、Apple により非推奨となっています。 詳細については、「画像のサイズとファイル名」を参照してください。

次のスクリーンショットに示すように、Android での代替解像度画像は、Android プロジェクト内の特別な名前のディレクトリに配置する必要があります。

Android の複数解像度の画像の場所

UWP の画像 ファイル名では、ファイル拡張子の前に、.scale-xxx のサフィックスを付けることができます。ここで xxx は、アセットに適用されるスケーリングの割合 (myimage.scale-200.png など) です。 その後は、スケール修飾子を使用せずに (たとえば、myimage.png だけで)、コードまたは XAML の中で画像を参照できます。 プラットフォームは、ディスプレイの現在の DPI に基づいて、最も近い適切なスケールのアセットを選択します。

画像表示の追加のコントロール

一部のコントロールには、画像を表示する次のようなプロパティがあります。

  • Button には、 ビットマップ イメージを Button に表示するように設定できる、ImageSource プロパティがあります。 詳細については、「ボタンでのビットマップの使用」を参照してください。

  • ImageButton には、 画像を ImageButton に表示するように設定できる、Source プロパティがあります。 詳細については、「画像ソースの設定」を参照してください。

  • ToolbarItem には、ファイル、埋め込みリソース、URI、またはストリームから画像を読み込むように設定できる、IconImageSource プロパティがあります。

  • ImageCell には、ファイル、埋め込みリソース、URI、またはストリームから画像を取得するように設定できる、ImageSource プロパティがあります。

  • Page= Page から派生した任意のページ型には、IconImageSource および BackgroundImageSource プロパティが備わっており、これにはファイル、埋め込みリソース、URI、またはストリームを割り当てることができます。 NavigationPageContentPage を表示している場合など特定の状況において、プラットフォームでそのサポートがある場合には、アイコンが表示されます。

    重要

    iOS では、Asset Catalog Image Set 内の画像から、Page.IconImageSource プロパティを設定することはできません。 代わりに、ファイル、埋め込みリソース、URI、またはストリームから、Page.IconImageSource プロパティのアイコン画像を読み込みます。

埋め込み画像

埋め込み画像も (ローカル画像のように) アプリケーションに同梱されますが、各アプリケーションのファイル構造に画像のコピーを含める代わりに、その画像 ファイルはリソースとしてアセンブリに埋め込まれています。 この画像配布の手法は、各プラットフォームで同じ画像が使用される場合に推奨されており、画像がコードにバンドルされるため、コンポーネントの作成に特に適しています。

プロジェクトに画像を埋め込むには、右クリックして新しい項目を追加し、追加したいイメージを選択します。 画像の既定では、Build Action: None が設定されているので、これを Build Action: EmbeddedResource に設定する必要があります。

ビルド アクションを埋め込まれたリソースに設定する

Build Action は、ファイルの [プロパティ ] ウィンドウで表示および変更できます。

この例でのリソース ID は、WorkingWithImages.beach.jpg です。 IDE では、このプロジェクトの既定の名前空間とファイル名を、各値の間にピリオド (.) を配置して連結し、この既定値を生成しています。

プロジェクト内のフォルダーに埋め込み画像を配置する場合、リソース ID の中のフォルダー名も、ピリオド (.) により区切られます。 画像 beach.jpgMyImages という名前のフォルダーに移動すると、リソース IDはWorkingWithImages.MyImages.beach.jpg となります

埋め込み画像を読み込むコードでは、次に示すように、リソース IDImageSource.FromResource メソッドに渡すだけです。

Image embeddedImage = new Image
{
    Source = ImageSource.FromResource("WorkingWithImages.beach.jpg", typeof(MyClass).GetTypeInfo().Assembly)
};

Note

ユニバーサル Windows プラットフォーム上のリリース モードで埋め込み画像の表示をサポートするには、イメージを検索するソース アセンブリを指定する、ImageSource.FromResource のオーバーロードを使用する必要があります。

現在、リソース識別子の暗黙的な変換は行なわれません。 代わりに、ImageSource.FromResource または new ResourceImageSource() を使用して、埋め込み画像を読み込む必要があります。

次のスクリーンショットに、各プラットフォームでの、埋め込み画像の表示結果を示します。

埋め込み画像を表示するサンプル アプリケーション

XAML

stringResourceImageSource にする組み込みの型コンバーターはないため、これらの型の画像を、XAML でネイティブに読み込むことはできません。 代わりに、単純なカスタム XAML マークアップ拡張を記述することで、XAML で指定されたリソース ID により画像を読み込めます。

[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}

Note

ユニバーサル Windows プラットフォーム上のリリース モードで埋め込み画像の表示をサポートするには、イメージを検索するソース アセンブリを指定する、ImageSource.FromResource のオーバーロードを使用する必要があります。

この拡張機能を使用するには、プロジェクトの適切な名前空間とアセンブリ値を使用して、XAML にカスタムの xmlns を追加します。 その後は、構文 {local:ImageResource WorkingWithImages.beach.jpg} を使用して画像ソースを設定できます。 完全な 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:WorkingWithImages;assembly=WorkingWithImages"
   x:Class="WorkingWithImages.EmbeddedImagesXaml">
 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>
</ContentPage>

埋め込み画像のトラブルシューティング

コードのデバッグ

特定の画像リソースが読み込まれない理由を知るのが難しいことがしばしばあります。この場合には、次のデバッグ コードをアプリケーションに一時的に追加すると、リソースが正しく構成されていることを確認するのに役立ちます。 これにより、指定したアセンブリに埋め込まれている既知のリソースがすべて コンソールに出力されるので、リソースの読み込みに関する問題をデバッグできます。

using System.Reflection;
// ...
// NOTE: use for debugging, not in released app code!
var assembly = typeof(MyClass).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
    System.Diagnostics.Debug.WriteLine("found resource: " + res);
}

他のプロジェクトに埋め込まれている画像

既定で ImageSource.FromResource メソッドは、ImageSource.FromResource メソッドを呼び出すコードと同じアセンブリ内のイメージのみを検索します。 上記のデバッグ コードを使用して、typeof() ステートメントを、各アセンブリ内にあることが既知である Type に変更すると、指定したリソースを含むアセンブリを特定できます。

ただし、埋め込み画像が検索されるソース アセンブリは、ImageSource.FromResource メソッドの引数として指定することも可能です。

var imageSource = ImageSource.FromResource("filename.png",
            typeof(MyClass).GetTypeInfo().Assembly);

イメージのダウンロード

次の XAML に示すように、画像は表示用に自動的にダウンロードされます。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="WorkingWithImages.DownloadImagesXaml">
  <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
    <Label Text="Image UriSource Xaml" />
    <Image Source="https://aka.ms/campus.jpg" />
    <Label Text="campus.jpg gets downloaded from microsoft.com" />
  </StackLayout>
</ContentPage>

これと同等の C# コードを次に示します。

var webImage = new Image {
     Source = ImageSource.FromUri(
        new Uri("https://aka.ms/campus.jpg")
     ) };

この ImageSource.FromUri メソッドでは Uri オブジェクトが必要であり、また、Uri から読み取った新しい UriImageSource が返されます。

また、URI 文字列のための暗黙的な変換もあるため、次の例も機能します。

webImage.Source = "https://aka.ms/campus.jpg";

次のスクリーンショットに、各プラットフォームでの、リモート画像の表示結果を示します。

ダウンロードした画像を表示するサンプル アプリケーション

ダウンロードしたイメージ のキャッシュ

UriImageSource は、ダウンロードした画像のキャッシュもサポートしており、次のプロパティを使用して構成されます。

  • CachingEnabled - キャッシュが有効になっているかどうか (既定は true)。
  • CacheValidity - 画像をローカルに格納する期間を定義 TimeSpan

キャッシュは既定で有効になっており、画像は 24 時間ローカルに保存されます。 特定の画像のキャッシュを無効にするには、次のように、その画像ソースをインスタンス化します。

image.Source = new UriImageSource { CachingEnabled = false, Uri = new Uri("https://server.com/image") };

特定のキャッシュ期間 (5 日など) を設定するには、次のように画像ソースをインスタンス化します。

webImage.Source = new UriImageSource
{
    Uri = new Uri("https://aka.ms/campus.jpg"),
    CachingEnabled = true,
    CacheValidity = new TimeSpan(5,0,0,0)
};

組み込みのキャッシュを使用すると、画像の一覧をスクロールするシナリオなどを非常に簡単にサポートできます。このシナリオでは、各セルに画像を設定 (またはバインド) し、セルが再びスクロールされた際、組み込みのキャッシュに画像を再読み込みさせることができます。

アニメーション GIF

Xamarin.Forms には、小さいアニメーション GIF の表示がサポートされています。 これを行うには、Image.Source プロパティをアニメーション GIF ファイルに設定します。

<Image Source="demo.gif" />

重要

Xamarin.Forms でのアニメーション GIF のサポートには、ファイルをダウンロードする機能が含まれていますが、アニメーション GIF のキャッシュやストリーミングはサポートされていません。

既定では、アニメーション GIF が読み込まれると再生されません。 これは、アニメーション GIF の再生または停止を制御する IsAnimationPlaying プロパティの既定値が false であるためです。 bool 型のこのプロパティは、BindableProperty オブジェクトによって動作します。これは、データ バインディングのターゲットにでき、またスタイルの設定が可能なことを意味します。

したがって、アニメーション GIF が読み込まれると、IsAnimationPlaying プロパティが true に設定されるまで再生されません。 その後、IsAnimationPlaying プロパティを false に 設定することで、再生を停止できます。 GIF 以外の画像ソースを表示する場合、このプロパティは効果がないことに注意してください。

Note

Android では、アニメーション GIF のサポートには、アプリケーションが高速レンダラーを使用する必要があり、レガシ レンダラーの使用にオプトインしている場合.、このサポートは機能しません。 UWP でのアニメーション GIF のサポートには、Windows 10 Anniversary Update (バージョン 1607) の最小リリースが必要です。

アイコンとスプラッシュ スクリーン

Image ビューには関係ありませんが、アプリケーション アイコンとスプラッシュ スクリーンも、Xamarin.Forms プロジェクトでの画像の重要な用途の 1 つです。

Xamarin.Forms アプリのアイコンとスプラッシュ スクリーンの設定は、各アプリケーション プロジェクトの中で行われます。 つまり、iOS、Android、UWP 用に、適切なサイズの画像が生成されます。 これらの画像では、各プラットフォームの要件に従って、名前付けと配置を行なう必要があります。

アイコン

これらのアプリケーション リソースの作成の詳細については、「 iOS での画像の操作」、「Google アイコノグラフィ」、「タイルとアイコンのアセットに関する UWP ガイドライン」、を参照してください。

さらに、FontImageSource オブジェクト内でフォント アイコン データを指定することで、Image ビューによりフォント アイコンを表示できます。 詳細については、「フォント ガイド」の「フォント アイコンを表示する」を参照してください。

スプラッシュ画面

スプラッシュ スクリーン (スタートアップ スクリーンまたはデフォルト画像とも呼ばれます) が必要なのは、iOS アプリケーションと UWP アプリケーションだけです。

Windows デベロッパー センターの、「iOS での画像の操作」と「スプラッシュ スクリーン」のドキュメントを参照してください。