ピクチャーハブに画像を保存する


WP7では、共通のメディアライブラリに保存されている画像データをPictureハブアプリから閲覧したり、他のアプリケーションから参照したりすることができます。

※他のアプリケーションから参照する方法は以下の記事を参考にどうぞ。
ピクチャーハブを利用する

本エントリでは、UIコントロールのキャプチャをPictureハブへ画像を保存する方法を紹介していきます。

エントリの内容の概略は以下の通りです。

  • Pictureハブへの画像保存方法
  • UIコントロールをキャプチャする(スクリーンショットの様な)方法

詳しくはつづきをどうぞ。

下準備

まず、参照とusing属性を追加します。
Microsoft.Xna.Framework.Mediaを利用するために、Microsoft.Xna.Frameworkを参照に追加します。

また、using属性として以下4つの項目を追加します。
#コメントでそれぞれ下記ソースコードのどのクラスで必要か明示しています。

using System.Windows.Resources; //StreamResourceInfo
using System.IO.IsolatedStorage; //IsolatedStorageFile
using System.Windows.Media.Imaging; // BitmapImage
using Microsoft.Xna.Framework.Media; //MediaLibrary

Pictureハブに保存を行う

Pictureハブに画像データを保存するためには、MediaLibraryクラスSavePictureメソッドを利用します。
SavePictureメソッド以外にも、SavePictureToCameraRollメソッドが用意されており、Pictureハブ内のどの場所に画像データを置くか選択することができます。
どちらのメソッドも引数は同じで、第一引数に保存ファイル名、第二引数に保存する画像データのStreamを指定します。

該当のサンプルコードは以下の通りです。
SavePictureメソッドの第二引数に指定するStreamは、分離ストレージのファイルストリームを取得できる、IsolatedStorageFileクラスOpenFileメソッドを利用して取得しています。

            // storeからfilestreamを取得
            fileStream = appStore.OpenFile(name, System.IO.FileMode.Open, System.IO.FileAccess.Read);

            MediaLibrary lib = new MediaLibrary();

            // 保存処理
            Picture picture = lib.SavePicture("claudia_san.jpg",fileStream);
            // picture = lib.SavePictureToCameraRoll("claudia_san.jpg",fileStream);
            fileStream.Close();

7行目でclaudia_san.jpgを「saved pictureアルバム」へ保存しています。8行目のコメントアウトの保存メソッドを利用すると、カメラロール内に保存することができます。

WriteableBitmapを利用して、Bitmapを作成する

今回はクラウディアさんの画像を利用しました。
クラウディアさんの画像を利用する際にはコピーライト表記を入れる必要があるため、以下のようなXAML構成としました。

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button Content="Save" Height="72" HorizontalAlignment="Left" Margin="-12,0,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
            <Image Height="523" HorizontalAlignment="Left" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="450" Source="/PictureSaveSample;component/Images/クラウディアSD2.jpg" />
            <TextBlock Height="30" HorizontalAlignment="Left" Margin="0,493,0,0" Name="textBlock1" Text="© 2011 Microsoft Corporation All Rights Reserved. " VerticalAlignment="Top" Foreground="Black" />
       </Grid>

しかし、Imageコントロールに配置したJpegファイルをそのままPictureハブ保存用のストリームに渡すと、コピーライト表記を行っているTextBlockが画像として保存できません。
WriteableBitmapクラスには、UIコントロールを画像として書き出す機能があるため、下記の様にImageコントロールとTextBlockを含んだGridパネルを用意し、Gridパネルごと画像として書き出しています。

        <Grid Height="529" HorizontalAlignment="Left" Margin="12,78,0,0" Name="saved_grid" VerticalAlignment="Top" Width="468" Grid.Row="1">
            <Image Height="523" HorizontalAlignment="Left" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="450" Source="/PictureSaveSample;component/Images/クラウディアSD2.jpg" />
            <TextBlock Height="30" HorizontalAlignment="Left" Margin="0,493,0,0" Name="textBlock1" Text="© 2011 Microsoft Corporation All Rights Reserved. " VerticalAlignment="Top" Foreground="Black" />
        </Grid>

WriteableBitmapを作成し、Jpegファイルを分離ストレージに保存する処理部は以下の引用のようになります。
分離ストレージの利用法については、こちらの記事を参考にどうぞ。

            // 分離ストレージへの保存ファイルの名前
            String name = "claudia_jpeg";

            // 分離ストレージへにテンポラリを保存するために
            var appStore = IsolatedStorageFile.GetUserStoreForApplication();
            if (appStore.FileExists(name))
            {
                appStore.DeleteFile(name);
            }

            IsolatedStorageFileStream fileStream = appStore.CreateFile(name);

            WriteableBitmap saveLayout = new WriteableBitmap(saved_grid,null);

            // 一度storeに保存する
            saveLayout.SaveJpeg(fileStream, saveLayout.PixelWidth, saveLayout.PixelHeight, 0, 85);
            fileStream.Close();

13行目でWriteableBimapクラスを生成しています。
第一引数に上記XAMLコード内で引用した、Gridパネルのsaved_gridを指定しています。
その後、16行目にてJpeg保存を行っています。
SaveJpegメソッドの引数には、ファイルストリーム、縦幅、横幅、Jpegの向き、Jpegのクォリティを指定しています。

本エントリのサンプルで保存した画像は以下のとおりです。
コピーライト表記が画像として反映されています。