読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

コピペで使える!Windowsストアアプリでカメラやライブラリから画像を読み込む方法

なぜコピペ形式にしたかというと依存関係プロパティでつまづいててバインドできないからです。

Windowsストアアプリで画像を読み込む場合、Webカメラからの取得、ファイルからの取得の2通りあります。良いストアアプリは、2通りのどちらでも実装できるのが望ましいと思います。

今回は、このままコピペでつかえるようなサンプルコードをつくったのでこれでカメラに対応したアプリを作ってみましょう。


XAML

<Button Content="Post" Width="80" Height="60" >
            <Button.Flyout>
                <MenuFlyout>
                    <MenuFlyoutItem x:Name="menuFlyoutItemMediaFromCamera" Text="From Camera" Click="menuFlyoutItemMediaFromCamera_Click" />
                    <MenuFlyoutItem x:Name="menuFlyoutItemMediaFromLibrary" Text="From Library" Click="menuFlyoutItemMediaFromLibrary_Click" />
                </MenuFlyout>
            </Button.Flyout>

        </Button>

ボタンを配置します。ボタンを押すと、Fyoutが出現し、カメラかライブラリからかの選択を要求するような形にします。

ボタンのクリックイベントです。

private async void menuFlyoutItemMediaFromCamera_Click(object sender, RoutedEventArgs e)
        {
            var camUI = new CameraCaptureUI();
            StorageFile file = await camUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
            if (file != null)
            {
                //byte[] data=await ReadImageBytesAsync(file);
                image.Source = await ReadImageBitmapAsync(file);
            }
        }

        private async void menuFlyoutItemMediaFromLibrary_Click(object sender, RoutedEventArgs e)
        {
            
            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            openPicker.FileTypeFilter.Add(".jpg");
            openPicker.FileTypeFilter.Add(".jpeg");
            openPicker.FileTypeFilter.Add(".png");

            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                //byte[] data = await ReadImageBytesAsync(file);
                image.Source =await ReadImageBitmapAsync(file);
            }
        }

        private async Task<byte[]> ReadImageBytesAsync(StorageFile file)
        {
            var stream = await file.OpenAsync(FileAccessMode.Read);
            var size = stream.Size;
            byte[] bytes = new byte[size];
            var reader = new DataReader(stream.GetInputStreamAt(0));
            await reader.LoadAsync((uint)size);
            reader.ReadBytes(bytes);
            return bytes;
        }

        private async Task<BitmapImage> ReadImageBitmapAsync(StorageFile file)
        {
            var stream = await file.OpenAsync(FileAccessMode.Read);
            var bitmap= new BitmapImage();
            await bitmap.SetSourceAsync(stream);
            return bitmap;
        }

MenuFlyoutのクリックイベントを2つ用意し、カメラから読み込む場合はCameraCaptureUIクラスを起動します。ライブラリから読み込む場合は、FileOpenPickerで取得をおこないます。

画像の読み込みは、
ReadImageBytesAsyncで画像をbyte配列で読み込みます。
ReadImageBitmapAsyncで画像をBitmapImage形式で読み込みます。

あとは、Imageコントロールを1個おいて、SourceプロパティにBitmapを指定すると画像が表示されます。

デバッグ時にはマニフェストの機能タブからWebカメラにチェックをつけましょう。
f:id:garicchi:20140116143147p:plain

ボタンを押すと選択を要求します
f:id:garicchi:20140116143325p:plain

カメラの場合は許可をしましょう。
f:id:garicchi:20140116143507p:plain


いえーい
f:id:garicchi:20140116143529p:plain

おまけ

なぜReadBytesAsyncをつくったかというとのいえさんのAsyncOAuthを使うときに必要になるからです。