酢ろぐ!

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

Pictures HubのCamera RollとSaved Picturesに画像を保存する

アプリ内で取得した画像や加工した写真をPicture Hubでユーザーから見れる場所に保存したいケースというのが多々あると思います。今回はカメラロールや「Saved Pictures」に保存する方法をご紹介します。

ただ、カメラロールに画像を保存するAPIは、Windows Phone 7.5(Windows Phone OS 7.0)以降対応となっており、Windows Phone OS 7.0の場合は「Saved Pictures」への保存しか出来ません。まずはそちらから。

Windows Phone OS 7.1時点では、Picture Hubの「カメラロール」および「SavedPicture」へ保存できるのはJPEG画像のみです。MediaLibrary.SavePictureメソッドの第二引数はJPEGフォーマットのStreamである必要があると書いています。

Saved Picturesへの保存

SavedPictureへの保存は、Windows Phone OS 7.0以降で使用することが可能です。

既に分離ストレージ(IsolatedStorage)に保存済みのJpeg画像を「Saved Pictures」に保存しましょう。保存には、Microsoft.Xna.Framework.Media.MediaLibraryクラスのSavePictureメソッドを使用します。

XNAFrameworkを使用しますので、参照の追加にて「Microsoft.Xna.Framework」を追加します。

private void ApplicationBarIconButton_Click(object sender, EventArgs e) {
    var fileName = "target.jpg";

    using (var store = IsolatedStorageFile.GetUserStoreForApplication()) {
        // 該当のファイルが存在しなかった場合保存しない
        if (!store.FileExists(fileName)) {
            return;
        }

        // 分離ストレージからJPEG画像のストリームを開く
        using (var strm = store.OpenFile(fileName, FileMode.Open, FileAccess.Read))
        using (var media = new Microsoft.Xna.Framework.Media.MediaLibrary()) {
            // XNAメディアライブラリを使用して画像を保存
            media.SavePicture(fileName, strm);
        }
    }
}

Windows Phone Emulatorでは、Picture Hubが非表示設定になっているのが原因か失敗してしまいますので、テストの際には実機で行ってください。

カメラロールへの保存

Windows Phone OS 7.1(Windows Phone 7.5)の場合は、カメラロールへの保存も可能になっています。コードは全く同じで、違いは保存にMicrosoft.Xna.Framework.Media.MediaLibraryクラスのSavePictureToCameraRollメソッドを使用している点です。

private void ApplicationBarIconButton_Click(object sender, EventArgs e) {
    var fileName = "target.jpg";

    using (var store = IsolatedStorageFile.GetUserStoreForApplication()) {
        // 該当のファイルが存在しなかった場合保存しない
        if (!store.FileExists(fileName)) {
            return;
        }

        // 分離ストレージからJPEG画像のストリームを開く
        using (var strm = store.OpenFile(fileName, FileMode.Open, FileAccess.Read))
        using (var media = new Microsoft.Xna.Framework.Media.MediaLibrary()) {
            // XNAメディアライブラリを使用して画像を保存
            media.SavePictureToCameraRoll(fileName, strm);
        }
    }
}

(2011.9.11 追記)SavePictureとSavePictureToCameraRollメソッドでPNGファイルが保存できない

Picture Hubへアプリ側から画像を保存するには、SavePictureとSavePictureToCameraRollメソッドでは、JPEGファイルしか保存することが出来ません。

// アプリ内のBackground.pngを読み込んでPNGファイルを保存する
using (var library = new MediaLibrary())
using (var strm = App.GetResourceStream(new Uri("Background.png", UriKind.Relative)).Stream) {
    library.SavePicture("dst.png", strm);
}

ネット上にPNGで保存出来ませんか?という質問がよく転がってるのですが結論としては無理なようです。そもそも、MediaLibrary.SavePictureメソッドの第二引数はJPEGフォーマットのStreamである必要があると書いてたりします。