第 13 章の概要: ビットマップ

Download Sampleサンプルのダウンロード

Note

この本は 2016 年春に発行されて以降、改訂されていません。 多くの情報はまだ価値がありますが、一部の資料は古くなっており、トピックの中にはまったく正しくないものまたは不完全なものもあります。

Xamarin.FormsImage 要素により、ビットマップが表示されます。 すべての Xamarin.Forms プラットフォームは、JPEG、PNG、GIF、および BMP ファイル形式をサポートしています。

Xamarin.Forms のビットマップは、次の 4 つの場所から取得されます。

  • URL で指定された Web 経由
  • 共有ライブラリにリソースとして埋め込まれている
  • プラットフォーム アプリケーション プロジェクトのリソースとして埋め込まれている
  • MemoryStream など、.NET Stream オブジェクトから参照できる任意の場所から

共有ライブラリのビットマップ リソースはプラットフォームに依存しませんが、プラットフォーム プロジェクトのビットマップ リソースはプラットフォーム固有です。

Note

本書の説明では、ポータブル クラス ライブラリについて触れますが、これは .NET Standard ライブラリに置き換えられています。 本のすべてのサンプル コードは、.NET Standard ライブラリを使用するように変換されています。

ビットマップを指定するには、ImageSource プロパティを、3 つの派生クラスを持つ抽象クラスである ImageSource 型のオブジェクトに設定します。

  • Uri プロパティに設定された Uri オブジェクトに基づいて、Web 経由でビットマップにアクセスするための UriImageSource
  • File プロパティに設定されたフォルダーとファイルのパスに基づいて、プラットフォーム アプリケーション プロジェクトに格納されているビットマップにアクセスするための FileImageSource
  • Stream プロパティに設定された Func から Stream が返され、それによって指定された .NET Stream オブジェクトを使用して、ビットマップを読み込むための StreamImageSource

または (より一般的な方法として)、ImageSource クラスの次の静的メソッドを使用できます。これらのいずれからも ImageSource オブジェクトが返されます。

  • Uri オブジェクトに基づいて Web 経由でビットマップにアクセスするための ImageSource.FromUri
  • アプリケーション PCL に埋め込みリソースとして格納されているビットマップにアクセスするための ImageSource.FromResource (別のソース アセンブリのビットマップにアクセスするには ImageSource.FromResource または ImageSource.FromResource)
  • プラットフォーム アプリケーション プロジェクトからビットマップにアクセスするための ImageSource.FromFile
  • Stream オブジェクトに基づいてビットマップを読み込むための ImageSource.FromStream

Image.FromResource メソッドに相当するクラスはありません。 UriImageSource クラスは、キャッシュを制御する必要がある場合に役立ちます。 FileImageSource クラスは XAML で役立ちます。 StreamImageSourceStream オブジェクトの非同期読み込みに、ImageSource.FromStream は同期読み込みに役立ちます。

プラットフォームに依存しないビットマップ

WebBitmapCode プロジェクトでは、ImageSource.FromUri を使用して Web 経由でビットマップを読み込みます。 Image 要素は ContentPageContent プロパティに設定されているため、ページのサイズに制限されます。 ビットマップのサイズに関係なく、制約付きの Image 要素はそのコンテナーのサイズに拡張され、ビットマップの縦横比を維持しながら、Image 要素内の最大サイズでビットマップが表示されます。 ビットマップ以外の Image の領域は、BackgroundColor を使用して色付けできます。

WebBitmapXaml サンプルは似ていますが、単に Source プロパティを URL に設定したものです。 変換は ImageSourceConverter クラスによって処理されます。

自動調整と塗りつぶし

ImageAspect プロパティを Aspect 列挙体の次のメンバーのいずれかに設定することで、ビットマップの拡大方法を制御できます。

  • AspectFit: 縦横比を維持します (既定値)。
  • Fill: 縦横比を考慮せず、領域全体に拡大します
  • AspectFill: ビットマップの一部をトリミングすることで、縦横比を維持しながら領域全体に拡大します

埋め込まれたリソース

ビットマップ ファイルを PCL、または PCL のフォルダーに追加できます。 EmbeddedResource[ビルド アクション] を指定します。 ResourceBitmapCode サンプルは、ImageSource.FromResource を使用してファイルを読み込む方法を示しています。 メソッドに渡されるリソース名は、アセンブリ名、それに続くドット、それに続く省略可能なフォルダー名とドット、それに続くファイル名で構成されます。

プログラムによって、ImageVerticalOptions および HorizontalOptions プロパティが LayoutOptions.Center に設定されます。これにより、Image 要素が制約なしになります。 Image とビットマップは同じサイズです。

  • iOS と Android では、Image はビットマップのピクセル サイズです。 ビットマップ ピクセルと画面ピクセルの間には 1 対 1 のマッピングがあります。
  • ユニバーサル Windows プラットフォームでは、Image はデバイスに依存しない単位のビットマップのピクセル サイズです。 ほとんどのデバイスでは、各ビットマップ ピクセルは複数の画面ピクセルを占有します。

StackedBitmap サンプルでは、XAML で縦の StackLayoutImage が配置されます。 ImageResourceExtension という名前のマークアップ拡張機能は、XAML の埋め込みリソースを参照するために役立ちます。 このクラスでは、それが配置されているアセンブリからのみリソースを読み込むため、ライブラリに配置することはできません。

サイズ変更の詳細

多くの場合、すべてのプラットフォーム間でビットマップのサイズを統一することをお勧めします。 StackedBitmap を試して、縦の StackLayoutImage 要素に WidthRequest を設定して、プラットフォーム間でサイズを統一することができますが、この手法では、サイズを小さくすることしかできません。

また、HeightRequest を設定して、プラットフォームで画像サイズを統一することもできますが、ビットマップの幅が制約されているため、この手法の汎用性が制限されます。 縦の StackLayout の画像では、HeightRequest を使用しないでください。

最適な方法は、デバイスに依存しない単位で電話の幅よりも広いビットマップから始め、デバイスに依存しない単位で WidthRequest を目的の幅に設定することです。 これは DeviceIndBitmapSize サンプルで示されています。

MadTeaParty を使うと、ルイス・キャロルの『不思議の国のアリス』の第 7 章と、ジョン・テニエルのオリジナルの挿絵が表示されます。

Triple screenshot of mad tea party

閲覧と待機

ImageBrowser サンプルを使用すると、ユーザーは Xamarin Web サイトに格納されているストック画像を閲覧できます。 .NET WebRequest クラスを使用して、ビットマップの一覧を含む JSON ファイルをダウンロードします。

Note

Xamarin.Forms プログラムでは、インターネット経由でファイルにアクセスするために、WebRequest ではなく HttpClient を使用する必要があります。

プログラムでは、何かが進行中であることを示すために ActivityIndicator が使用されます。 各ビットマップが読み込まれているとき、Image の読み取り専用の IsLoading プロパティは true になります。 IsLoading プロパティはバインド可能なプロパティによってサポートされているため、そのプロパティが変更されると PropertyChanged イベントが発生します。 プログラムによって、このイベントにハンドラーがアタッチされ、IsLoaded の現在の設定が使用され、ActivityIndicatorIsRunning プロパティが設定されます。

ストリーミング ビットマップ

ImageSource.FromStream メソッドを使うと、.NET Stream に基づいて ImageSource が作成されます。 メソッドには、Stream オブジェクトを返す Func オブジェクトを渡す必要があります。

ストリームへのアクセス

BitmapStreams サンプルは、ImaageSource.FromStream メソッドを使用して、埋め込みリソースとして格納されているビットマップを読み込み、Web 経由でビットマップを読み込む方法を示しています。

実行時のビットマップの生成

すべての Xamarin.Forms プラットフォームは、非圧縮の BMP ファイル形式をサポートしています。これは、コードで簡単に構築し、MemoryStream に格納できます。 Xamrin.FormsBook.Toolkit ライブラリの BmpMaker クラスに実装されているように、この手法により、実行時にビットマップをアルゴリズム的に作成できます。

"Do It Yourself" DiyGradientBitmap サンプルは、BmpMaker を使用してグラデーション画像でビットマップを作成する方法を示しています。

プラットフォーム固有のビットマップ

すべての Xamarin.Forms プラットフォームでは、プラットフォーム アプリケーション アセンブリにビットマップを格納できます。 Xamarin.Forms アプリケーションによって取得された場合、これらのプラットフォーム ビットマップは FileImageSource 型です。 それらを以下に使用します。

プラットフォーム アセンブリには、アイコンとスプラッシュ スクリーンのビットマップが既に含まれています。

  • iOS プロジェクトの Resources フォルダー
  • Android プロジェクトの Resources フォルダーのサブフォルダー
  • Windows プロジェクトでは、Assets フォルダー内 (ただし、Windows プラットフォームではビットマップはそのフォルダーに限定されません)

PlatformBitmaps サンプルでは、コードを使用してプラットフォーム アプリケーション プロジェクトのアイコンを表示します。

ビットマップの解像度

すべてのプラットフォームで、さまざまなデバイス解像度用にビットマップ画像の複数のバージョンを保存できます。 実行時に、画面のデバイス解像度に基づいて適切なバージョンが読み込まれます。

iOS では、これらのビットマップはファイル名のサフィックスによって区別されます。

  • 160 DPI デバイスの場合はサフィックスなし (デバイスに依存しない単位に対して 1 ピクセル)
  • 320 DPI デバイスの場合は '@2x' のサフィックス (DIU に対して 2 ピクセル)
  • 480 DPI デバイスの場合は '@3x' のサフィックス (DIU に対して 3 ピクセル)

1 インチ四方として表示することを目的としたビットマップは、次の 3 つのバージョンに存在します。

  • 160 ピクセル四方の MyImage.jpg
  • 320 ピクセル四方の MyImage@2x.jpg
  • 480 ピクセル四方の MyImage@3x.jpg

このプログラムでは、このビットマップを MyImage.jpg として参照しますが、適切なバージョンは画面の解像度に基づいて実行時に取得されます。 制約なしの場合、ビットマップは常に 160 のデバイスに依存しない単位でレンダリングされます。

Android の場合、ビットマップは Resources フォルダーのさまざまなサブフォルダーに格納されます。

  • 120 DPI デバイスの場合は drawable-ldpi (低い DPI) (DIU に対して 0.75 ピクセル)
  • 160 DPI デバイスの場合は drawable-mdpi (中) (DIU に対して 1 ピクセル)
  • 240 DPI デバイスの場合は drawable-hdpi (高い) (DIU に対して 1.5 ピクセル)
  • 320 DPI デバイスの場合は drawable-xhdpi (非常に高い) (DIU に対して 2 ピクセル)
  • 480 DPI デバイスの場合は drawable-xxhdpi (2 倍の高さ) (DIU に対して 3 ピクセル)
  • 640 DPI デバイスの場合は drawable-xxxhdpi (3 倍の高さ) (DIU に対して 4 ピクセル)

1 インチ四方でレンダリングされることを目的としたビットマップの場合、ビットマップのさまざまなバージョンは名前は同じですが、サイズが異なり、これらのフォルダーに格納されます。

  • 120 ピクセル四方の drawable-ldpi/MyImage.jpg
  • 160 ピクセル四方の drawable-mdpi/MyImage.jpg
  • 240 ピクセル四方 drawable-hdpi/MyImage.jpg
  • 320 ピクセル四方の drawable-xhdpi/MyImage.jpg
  • 480 ピクセル四方の drawable-xxhdpi/MyImage.jpg
  • 640 ピクセル四方の drawable-xxxhdpi/MyImage.jpg

ビットマップは常に 160 のデバイスに依存しない単位でレンダリングされます (標準の Xamarin.Forms ソリューション テンプレートには、hdpi、xhdpi、xxhdpi の各フォルダーのみが含まれます)。

UWP プロジェクトでは、デバイスに依存しない単位ごとのピクセル単位のスケール ファクター (%) で構成されるビットマップ名前付け規則をサポートしています。たとえば、次のとおりです。

  • 320 ピクセル四方の MyImage.scale-200.jpg

一部のパーセンテージのみが有効です。 本書のサンプル プログラムには、サフィックスが scale-200 の画像のみが含まれていますが、現在の Xamarin.Forms ソリューション テンプレートには、scale-100scale-125scale-150scale-400 が含まれています。

プラットフォーム プロジェクトにビットマップを追加する場合、[ビルド アクション] は次のようになります。

  • iOS: BundleResource
  • Android: AndroidResource
  • UWP: Content

ImageTap サンプルでは、TapGestureRecognizer がインストールされた Image 要素で構成される 2 つのボタンのようなオブジェクトを作成します。 これは、オブジェクトが 1 インチ四方であることが意図されています。 ImageSource プロパティは、プラットフォーム上の異なる可能性のあるファイル名を参照するために、OnPlatform および On オブジェクトを使用して設定されます。 ビットマップ画像にはピクセル サイズを示す数字が含まれているため、ビットマップが取得およびレンダリングされるサイズを確認できます。

ツールバーとそのアイコン

プラットフォーム固有のビットマップの主な用途の 1 つは、Xamarin.Forms ツールバーです。これを構築するには、ToolbarItem オブジェクトを、Page で定義された ToolbarItems コレクションに追加します。 ToobarItemMenuItem から派生し、そこからいくつかのプロパティを継承します。

最も重要な ToolbarItem プロパティは、次のとおりです。

  • プラットフォームと Order に応じて表示されるテキストの場合は Text
  • プラットフォームと Order に応じて表示される可能性のある画像の場合は型 FileImageSourceIcon
  • DefaultPrimary、および Secondary という 3 つのメンバーを持つ列挙体である型 ToolbarItemOrderOrder

Primary 項目の数は 3 つまたは 4 つに制限する必要があります。 すべての項目に Text 設定を含める必要があります。 ほとんどのプラットフォームでは、Primary 項目のみに Icon が必要ですが、Windows 8.1 ではすべての項目に Icon が必要です。 アイコンは、デバイスに依存しない 32 単位四方にする必要があります。 FileImageSource 型は、それらがプラットフォーム固有であることを示します。

ToolbarItem を使うと、タップしたときに Button のように Clicked イベントが発生します。 ToolbarItem では、MVVM に関連してよく使用される Command および CommandParameter プロパティもサポートされます (「第 18 章 MVVM」を参照してください)。

iOS と Android のいずれでも、ツールバーを表示するページは NavigationPage であるか、NavigationPage によってナビゲートされるページである必要があります。 ToolbarDemo プログラムによって、ContentPage 引数を使用して、App クラスの MainPage プロパティが NavigationPage コンストラクターに設定されます。これは、ツール バーの構築とイベント ハンドラーを示すものです。

ボタン画像

ButtonImage サンプルに示されているように、プラットフォーム固有のビットマップを使用して、ButtonImage プロパティを、デバイスに依存しない 32 単位四方のビットマップに設定することもできます。

Note

ボタンでの画像の使用が強化されました。 「ボタンにビットマップを使用する」を参照してください。