takataka430’s blog

.NET系を中心に勉強したことのまとめを書きます

Xamarin.Formsで写真を撮る

久々のXamarinの記事です。Xamarin.Formsで写真を撮影し、撮った画像を表示する方法を調査しました。
※手元にiPhoneがないため、動作確認できているのはAndroidのみとなります。

開発環境

Visual Studio 2019
Xamarin.Forms 5.0.0.2012
Xamarin.Essential 1.6.1

利用するメソッドについて

写真を撮るためには名前空間Xamarin.EssentialsMediaPickerクラスのCapturePhotoAsyncメソッドを利用します。戻り値はTask<FileResult>です。
CapturePhotoAsyncを使って撮った画像は端末内に保存されます。保存場所はFileResultクラスのFullPathプロパティで取得可能です。今回は画像が端末内にたまらないよう、削除するようにしてみました。

コード

画面は以下のようにします。ボタンと画像を表示するだけのシンプルなものです。(レイアウトはお好みで)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XF_CustomVisionStudy.MainPage">
    <StackLayout>
        <Button Text="test" 
                Clicked="TakePhoto" 
                HorizontalOptions="Center"/>
        <Image  x:Name="image"/>
    </StackLayout>
</ContentPage>

次にコードビハインドは以下のようにします。

using System;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace XF_CustomVisionStudy
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private async void TakePhoto(object sender, EventArgs e)
        {
            try
            {
                //写真をとる
                var photo = await MediaPicker.CapturePhotoAsync();
                
                if(photo !=null)
                {
                    //撮った写真を画面に表示する
                    var stream = await photo.OpenReadAsync();
                    image.Source = ImageSource.FromStream(() => stream);
                    
                    //画像の保存場所を取得
                    var imagePath = photo.FullPath;
                    //画像を削除する
                    System.IO.File.Delete(imagePath);
                }
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

最後にOSごとの設定を行います。

Androidの場合

AndroidManifest.xmlの中に以下を追記します。(<manifest>の内側です)

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

Android11の場合は以下も必要です。(無いとエラーになります)

<queries>
  <intent>
    <action android:name="android.media.action.IMAGE_CAPTURE" />
  </intent>
</queries>

iOSの場合

info.plistに以下を追記します。

<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to take photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs access to microphone for taking videos.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs access to the photo gallery for picking photos and videos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to photos gallery for picking photos and videos.</string>

以上で完了です。実行すると、ボタンクリックで写真を撮ることができ、撮影した画像がボタンの下に表示されます。

参考ページ

Xamarin.Essentials: Media Picker - Xamarin | Microsoft Docs
MediaPicker.CapturePhotoAsync(MediaPickerOptions) Method (Xamarin.Essentials) | Microsoft Docs
FileResult Class (Xamarin.Essentials) | Microsoft Docs
Xamarin Froms で写真を撮影する - rksoftware