酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでPictures Hubに保存されている写真の情報を取得する

Pictures HubのCamera RollとSaved Picturesに画像を保存する」に保存する方法を書いたので、Pictures Hubのアルバム情報や写真を取得する方法を紹介します。今回は写真を取得してみましょう。

Pictures Hubへ写真を保存した時には、XNA Frameworkを使用しました。アルバム情報の取得や写真の取得に関しても同様にXNA Frameworkを利用します。

保存時と同様に、プロジェクトを右クリックして、メニューから[参照の追加]を選択します。参照の追加ダイアログからMicrosoft.Xna.Frameworkを選択します。

写真の取得

Microsoft.Xna.Framework.Media名前空間のMediaLibraryクラスを利用して、デバイス内に保存されているすべての写真を取得することが出来ます。

シンプルに写真を取得したい場合は、PhotoChooserTaskを使用すると良いでしょう。こちらについて詳細は「PhotoChooserTaskでの写真の取得」をお読みください。

コード(C#)

MediaLibraryクラスのインスタンスを生成して、PicturesプロパティにてPictures Hubに登録されている写真コレクションを取得します。コレクションから1枚1枚写真のサムネイル画像を取得して、ItemsSourceプロパティに設定しています。

using System.Linq;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework.Media;

namespace GetPicturesTest {
    public partial class MainPage : PhoneApplicationPage {
        // コンストラクター
        public MainPage() {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
            // XNA Frameworkのメディアライブラリを利用する
            using (var ml = new MediaLibrary()) {

                // Pictures Hubに保存されている全ての写真を取得する
                // ここで取得出来る写真は、オフライン(デバイス内の)写真のみ
                var pictures = ml.Pictures;

                // 写真のサムネイル画像を取得して、リストに表示する
                listBox1.ItemsSource = pictures.Select(picture => {
                    var bmpImage = new BitmapImage();
                    bmpImage.SetSource(picture.GetThumbnail());
                    return bmpImage;
                });
            }
        }
    }
}

これでコード側の実装は完了です。

XAML

写真を表示するためListBoxコントロールをContentPanelへ配置します。画像を表示したいのでアイテムテンプレートにてImageコントロールを定義します。ItemsSourceで設定されたサムネイル画像のリストをバインディングしています。

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ListBox Name="listBox1">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Image Source="{Binding}" 
                        Height="50" Width="50" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>	
    </ListBox>
</Grid>

素直に実行するとこんな感じの表示になってしまいます。ListBoxなので縦に画像が並んでいる感じになります。

このままだと少し不格好ですので、Windows Phone Toolkit for SilverlightのWrapPanelを使って表示を整えます。

もし、Windows Phone Toolkitがインストールされているのであれば、参照の追加ダイアログからMicrosoft.Phone.Controls.Tookitを選択して、参照の追加をしてください。

ItemsPanelTemplateは、アイテム単位のレイアウトを定義します。これをデフォルトのStackPanelからWrapPanelに変更します。

<phone:PhoneApplicationPage
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" 
    x:Class="GetPicturesTest.MainPage"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
    
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="SOFTBUILD" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="GetPicturesTest" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <ListBox x:Name="listBox1">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <toolkit:WrapPanel/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <Image Source="{Binding}" 
                                Height="72" Width="72" 
                                Margin="6"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>	
			</ListBox>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>

画面上にたくさんの画像が並ぶのは圧巻ですね。