第 13 章の概要: ビットマップ
Note
この本は 2016 年春に発行されて以降、改訂されていません。 多くの情報はまだ価値がありますが、一部の資料は古くなっており、トピックの中にはまったく正しくないものまたは不完全なものもあります。
Xamarin.FormsImage
要素により、ビットマップが表示されます。 すべての Xamarin.Forms プラットフォームは、JPEG、PNG、GIF、および BMP ファイル形式をサポートしています。
Xamarin.Forms のビットマップは、次の 4 つの場所から取得されます。
- URL で指定された Web 経由
- 共有ライブラリにリソースとして埋め込まれている
- プラットフォーム アプリケーション プロジェクトのリソースとして埋め込まれている
MemoryStream
など、.NETStream
オブジェクトから参照できる任意の場所から
共有ライブラリのビットマップ リソースはプラットフォームに依存しませんが、プラットフォーム プロジェクトのビットマップ リソースはプラットフォーム固有です。
Note
本書の説明では、ポータブル クラス ライブラリについて触れますが、これは .NET Standard ライブラリに置き換えられています。 本のすべてのサンプル コードは、.NET Standard ライブラリを使用するように変換されています。
ビットマップを指定するには、Image
の Source
プロパティを、3 つの派生クラスを持つ抽象クラスである ImageSource
型のオブジェクトに設定します。
Uri
プロパティに設定されたUri
オブジェクトに基づいて、Web 経由でビットマップにアクセスするためのUriImageSource
File
プロパティに設定されたフォルダーとファイルのパスに基づいて、プラットフォーム アプリケーション プロジェクトに格納されているビットマップにアクセスするためのFileImageSource
Stream
プロパティに設定されたFunc
からStream
が返され、それによって指定された .NETStream
オブジェクトを使用して、ビットマップを読み込むためのStreamImageSource
または (より一般的な方法として)、ImageSource
クラスの次の静的メソッドを使用できます。これらのいずれからも ImageSource
オブジェクトが返されます。
Uri
オブジェクトに基づいて Web 経由でビットマップにアクセスするためのImageSource.FromUri
- アプリケーション PCL に埋め込みリソースとして格納されているビットマップにアクセスするための
ImageSource.FromResource
(別のソース アセンブリのビットマップにアクセスするにはImageSource.FromResource
またはImageSource.FromResource
) - プラットフォーム アプリケーション プロジェクトからビットマップにアクセスするための
ImageSource.FromFile
Stream
オブジェクトに基づいてビットマップを読み込むためのImageSource.FromStream
Image.FromResource
メソッドに相当するクラスはありません。 UriImageSource
クラスは、キャッシュを制御する必要がある場合に役立ちます。 FileImageSource
クラスは XAML で役立ちます。 StreamImageSource
は Stream
オブジェクトの非同期読み込みに、ImageSource.FromStream
は同期読み込みに役立ちます。
プラットフォームに依存しないビットマップ
WebBitmapCode プロジェクトでは、ImageSource.FromUri
を使用して Web 経由でビットマップを読み込みます。 Image
要素は ContentPage
の Content
プロパティに設定されているため、ページのサイズに制限されます。 ビットマップのサイズに関係なく、制約付きの Image
要素はそのコンテナーのサイズに拡張され、ビットマップの縦横比を維持しながら、Image
要素内の最大サイズでビットマップが表示されます。 ビットマップ以外の Image
の領域は、BackgroundColor
を使用して色付けできます。
WebBitmapXaml サンプルは似ていますが、単に Source
プロパティを URL に設定したものです。 変換は ImageSourceConverter
クラスによって処理されます。
自動調整と塗りつぶし
Image
の Aspect
プロパティを Aspect
列挙体の次のメンバーのいずれかに設定することで、ビットマップの拡大方法を制御できます。
AspectFit
: 縦横比を維持します (既定値)。Fill
: 縦横比を考慮せず、領域全体に拡大しますAspectFill
: ビットマップの一部をトリミングすることで、縦横比を維持しながら領域全体に拡大します
埋め込まれたリソース
ビットマップ ファイルを PCL、または PCL のフォルダーに追加できます。 EmbeddedResource の [ビルド アクション] を指定します。 ResourceBitmapCode サンプルは、ImageSource.FromResource
を使用してファイルを読み込む方法を示しています。 メソッドに渡されるリソース名は、アセンブリ名、それに続くドット、それに続く省略可能なフォルダー名とドット、それに続くファイル名で構成されます。
プログラムによって、Image
の VerticalOptions
および HorizontalOptions
プロパティが LayoutOptions.Center
に設定されます。これにより、Image
要素が制約なしになります。 Image
とビットマップは同じサイズです。
- iOS と Android では、
Image
はビットマップのピクセル サイズです。 ビットマップ ピクセルと画面ピクセルの間には 1 対 1 のマッピングがあります。 - ユニバーサル Windows プラットフォームでは、
Image
はデバイスに依存しない単位のビットマップのピクセル サイズです。 ほとんどのデバイスでは、各ビットマップ ピクセルは複数の画面ピクセルを占有します。
StackedBitmap サンプルでは、XAML で縦の StackLayout
に Image
が配置されます。 ImageResourceExtension
という名前のマークアップ拡張機能は、XAML の埋め込みリソースを参照するために役立ちます。 このクラスでは、それが配置されているアセンブリからのみリソースを読み込むため、ライブラリに配置することはできません。
サイズ変更の詳細
多くの場合、すべてのプラットフォーム間でビットマップのサイズを統一することをお勧めします。
StackedBitmap を試して、縦の StackLayout
の Image
要素に WidthRequest
を設定して、プラットフォーム間でサイズを統一することができますが、この手法では、サイズを小さくすることしかできません。
また、HeightRequest
を設定して、プラットフォームで画像サイズを統一することもできますが、ビットマップの幅が制約されているため、この手法の汎用性が制限されます。 縦の StackLayout
の画像では、HeightRequest
を使用しないでください。
最適な方法は、デバイスに依存しない単位で電話の幅よりも広いビットマップから始め、デバイスに依存しない単位で WidthRequest
を目的の幅に設定することです。 これは DeviceIndBitmapSize サンプルで示されています。
MadTeaParty を使うと、ルイス・キャロルの『不思議の国のアリス』の第 7 章と、ジョン・テニエルのオリジナルの挿絵が表示されます。
閲覧と待機
ImageBrowser サンプルを使用すると、ユーザーは Xamarin Web サイトに格納されているストック画像を閲覧できます。 .NET WebRequest
クラスを使用して、ビットマップの一覧を含む JSON ファイルをダウンロードします。
Note
Xamarin.Forms プログラムでは、インターネット経由でファイルにアクセスするために、WebRequest
ではなく HttpClient
を使用する必要があります。
プログラムでは、何かが進行中であることを示すために ActivityIndicator
が使用されます。 各ビットマップが読み込まれているとき、Image
の読み取り専用の IsLoading
プロパティは true
になります。 IsLoading
プロパティはバインド可能なプロパティによってサポートされているため、そのプロパティが変更されると PropertyChanged
イベントが発生します。 プログラムによって、このイベントにハンドラーがアタッチされ、IsLoaded
の現在の設定が使用され、ActivityIndicator
の IsRunning
プロパティが設定されます。
ストリーミング ビットマップ
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
型です。 それらを以下に使用します。
MenuItem
のIcon
プロパティToolbarItem
のIcon
プロパティButton
のImage
プロパティ
プラットフォーム アセンブリには、アイコンとスプラッシュ スクリーンのビットマップが既に含まれています。
- 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-100、scale-125、scale-150、scale-400 が含まれています。
プラットフォーム プロジェクトにビットマップを追加する場合、[ビルド アクション] は次のようになります。
- iOS: BundleResource
- Android: AndroidResource
- UWP: Content
ImageTap サンプルでは、TapGestureRecognizer
がインストールされた Image
要素で構成される 2 つのボタンのようなオブジェクトを作成します。 これは、オブジェクトが 1 インチ四方であることが意図されています。 Image
の Source
プロパティは、プラットフォーム上の異なる可能性のあるファイル名を参照するために、OnPlatform
および On
オブジェクトを使用して設定されます。 ビットマップ画像にはピクセル サイズを示す数字が含まれているため、ビットマップが取得およびレンダリングされるサイズを確認できます。
ツールバーとそのアイコン
プラットフォーム固有のビットマップの主な用途の 1 つは、Xamarin.Forms ツールバーです。これを構築するには、ToolbarItem
オブジェクトを、Page
で定義された ToolbarItems
コレクションに追加します。 ToobarItem
は MenuItem
から派生し、そこからいくつかのプロパティを継承します。
最も重要な ToolbarItem
プロパティは、次のとおりです。
- プラットフォームと
Order
に応じて表示されるテキストの場合はText
- プラットフォームと
Order
に応じて表示される可能性のある画像の場合は型FileImageSource
のIcon
Default
、Primary
、およびSecondary
という 3 つのメンバーを持つ列挙体である型ToolbarItemOrder
のOrder
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 サンプルに示されているように、プラットフォーム固有のビットマップを使用して、Button
の Image
プロパティを、デバイスに依存しない 32 単位四方のビットマップに設定することもできます。
Note
ボタンでの画像の使用が強化されました。 「ボタンにビットマップを使用する」を参照してください。