Sunday September 8th, 2019

Xamarin.Forms Taking Picture

By Ebubekir Sezer

Hello, when i was develop an application, i was need the take a picture and pick the picture. I researched about the taking and picking picture and i find the Xam.Plugin.Media plugin which created by the James Montemagno. For the use that plugin, we need to make some arranges.

Firstly, after the creating project we need the add the Xam.Plugin.Media. Later inside of the Android platform and AndroidManifest, we need to add the below codes between the application tags. The Application ID in the code is your package name so change it.

<provider android:name="android.support.v4.content.FileProvider" 
				android:authorities="${applicationId}.fileprovider" 
				android:exported="false" 
				android:grantUriPermissions="true">
			<meta-data android:name="android.support.FILE_PROVIDER_PATHS" 
				android:resource="@xml/file_paths"></meta-data>
</provider>

Our job is done inside of the AndroidManifest. Now we should go Resources and create a folder which name is xml. In this folder, I create the file which name is file_paths.xml and wrote these below codes;

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="my_images" path="Pictures" />
    <external-files-path name="my_movies" path="Movies" />
</paths>

After that, go to Main Activity and initialize the plugin.

CrossCurrentActivity.Current.Init(this, bundle);

Plugin will work. So now we need the make the take picture, video and pick picture and video. Before that process, I made a simple design inside of the MainPage.xaml. I added a picture and 4 buttons.

<StackLayout Margin="15">
        <Image x:Name="myImage"
               Source="defaultimage"
               WidthRequest="250"
               HeightRequest="250"
               Aspect="AspectFit"/>
        <Button Text="Take Picture"
                FontAttributes="Bold"
                TextColor="White"
                BackgroundColor="DarkGreen"
                Clicked="TakePicture_Clicked"/>
        <Button Text="Pick Picture"
                FontAttributes="Bold"
                TextColor="White"
                BackgroundColor="DarkTurquoise"
                Clicked="PickPicture_Clicked"/>
        <Button Text="Take Video"
                FontAttributes="Bold"
                TextColor="White"
                BackgroundColor="DarkGray"
                Clicked="TakeVideo_Clicked"/>
        <Button Text="Pick Video"
                FontAttributes="Bold"
                TextColor="White"
                BackgroundColor="DarkMagenta"
                Clicked="PickVideo_Clicked"/>
    </StackLayout>

I wrote the event for the each buttons. I started with the taking picture button. Firstly, I am controlling the situation of the camera. If the condition will be success, Camera will be open with the TakePhotoAsync() event. I give the properties of the image. For the showing image in the MainPage.xaml, I return a stream with the ImageSource.FromStream. So our image will be appear.

 private async void TakePicture_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if(!CrossMedia.Current.IsTakePhotoSupported || !CrossMedia.Current.IsCameraAvailable)
            {
                await DisplayAlert("ERROR", "Camera is NOT available", "OK");
                return;
            }

            mediaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
            {
                Directory = "Sample",
                Name = "myImage.jpg"
            }); 

            if(mediaFile == null)
            {
                return;
            }

            myImage.Source = ImageSource.FromStream(() =>
            {
                return mediaFile.GetStream();
            });
        }

For the picking picture from the gallery, I control the supporting of the phone. If it is successfull, I pick the image with PickPhotoAsync event. For the showing image in the MainPage.xaml, again i use ImageSource.FromStream and we get the stream with GetStream function and we returned as an image.

 private async void PickPicture_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsPickPhotoSupported)
            {
                await DisplayAlert("ERROR", "Pick Photo is NOT supported", "OK");
                return;
            }

            var file = await CrossMedia.Current.PickPhotoAsync();

            if(file == null)
            {
                return;
            }

            myImage.Source = ImageSource.FromStream(() =>
            {
                var stream = file.GetStream();
                file.Dispose();
                return stream;
            });
        }

Taking video and picking video process same as taking picture and picking picture so i will directly wrote the codes below.

 // Taking Video
        private async void TakeVideo_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if(!CrossMedia.Current.IsTakeVideoSupported || !CrossMedia.Current.IsCameraAvailable)
            {
                await DisplayAlert("ERROR", "Camera is NOT available", "OK");
                return;
            }

            mediaFile = await CrossMedia.Current.TakeVideoAsync(new StoreVideoOptions
            {
                Directory = "Sample",
                Name = "myVideo.jpg"
            });

            if(mediaFile == null)
            {
                return;
            }

            myImage.Source = ImageSource.FromStream(() =>
            {
                return mediaFile.GetStream();
            });
        }

        //Picking Video
        private async void PickVideo_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsPickVideoSupported)
            {
                await DisplayAlert("ERROR", "Pick Video is NOT supported", "OK");
                return;
            }

            var file = await CrossMedia.Current.PickVideoAsync();

            if(file == null)
            {
                return;
            }

            myImage.Source = ImageSource.FromStream(() =>
             {
                 var stream = file.GetStream();
                 file.Dispose();
                 return stream;
             });
        }

Here is the output of the application;

You can ask your questions via e-mail or comments.