— Xamarin, CSharp, Android, Mobile Development — 2 min read
It's very easy if you know the way. In the upcoming few lines, I'm gonna show you how to take photos in Xamarin.Forms. So without talking some standard opening trash, let's get started.
First thing first, we need to install a NuGet package. We gonna use James Montemagno's MediaPlugin to make our life easier. This package abstracts all the heavy lifting and gives us a simple and elegant way to get our job done.
Add the following line to your Shared project's .csproj
file inside the <ItemGroup></ItemGroup>
tag.
1<PackageReference Include="Xam.Plugin.Media" Version="5.0.1" />
Alternatively you can use NuGet package manager to install the package. Just search for Xam.Plugin.Media
and install the package.
Now let's do some works within our Android Project.
Add a new folder called XML into your Resources folder and add a new XML file called file_paths.xml. Make sure that this XML file has a Build Action of Android Resource.
Add the following code:
1<?xml version="1.0" encoding="utf-8" ?>2<paths xmlns:android="http://schemas.android.com/apk/res/android">3 <external-files-path name="my_images" path="Pictures" />4 <external-files-path name="my_movies" path="Movies" />5</paths>
Now open the AndroidManifest.xml file and add one of the following code inside the <application></application>
tag that best suits your project.
1<provider android:name="android.support.v4.content.FileProvider"2 android:authorities="${applicationId}.fileprovider"3 android:exported="false"4 android:grantUriPermissions="true">5 <meta-data android:name="android.support.FILE_PROVIDER_PATHS"6 android:resource="@xml/file_paths"/>7</provider>
1<provider android:name="androidx.core.content.FileProvider"2 android:authorities="${applicationId}.fileprovider"3 android:exported="false"4 android:grantUriPermissions="true"> 5 <meta-data android:name="android.support.FILE_PROVIDER_PATHS"6 android:resource="@xml/file_paths"/>7</provider>
Open the AssemblyInfo.cs and add the following lines to consume the permissions.
1[assembly: UsesFeature("android.hardware.camera", Required = false)]2[assembly: UsesFeature("android.hardware.camera.autofocus", Required = false)]
Now we are ready to start writing some actual codes and we are done with the Android Project for now. Let's get back to work with the Shared Project.
Take a view and place the following lines to capture and display the image.
1<Image x:Name="PhotoImage" />2<Button x:Name="CameraButton" Text="Take Photo" Clicked="CameraButton_Clicked" />
Here we will take a photo when the x:Name="CameraButton"
is pressed and display the captured image stream in the x:Name="PhotoImage"
component.
Now open the view's corresponding .cs
file. And implement the following method -
1private async void CameraButton_Clicked(object sender, EventArgs e)2{3 var cameraMediaOptions = new StoreCameraMediaOptions4 {5 DefaultCamera = CameraDevice.Rear,6
7 // Set the value to true if you want to save the photo to your public storage.8 SaveToAlbum = true,9
10 // Give the name of the folder you want to save to11 Directory = "MyAppName",12
13 // Give a photo name of your choice,14 // or set it to null if you want to use the default naming convention15 Name = null,16
17 // Set the compression quality18 // 0 = Maximum compression but worse quality19 // 100 = Minimum compression but best quality20 CompressionQuality = 10021 };22 MediaFile photo = await CrossMedia.Current.TakePhotoAsync(cameraMediaOptions);23 if (photo == null) return;24 PhotoImage.Source = ImageSource.FromStream(() => photo.GetStream());25}
Now if you run the app and perform the operations, you'll have a kind of similar experience as the following GIF.
If you set SaveToAlbum = false
you won't see the image inside the directory but, it always get's saved to the app's private folder. Most of the time you want that to be deleted to save storage.
To do this, you need to get the image's private path and delete it manually. The fun fact is, it's a very easy thing to do.
Add the following lines at the end of CameraButton_Clicked
method.
1// Get the public album path2var publicPhotoPath = photo.AlbumPath;3Debug.WriteLine(publicPhotoPath);4
5// Get private path6var privatePhotoPath = photo.Path;7Debug.WriteLine(privatePhotoPath);8
9// Delete the file10var res = DeleteFileByPath(privatePhotoPath);11Debug.WriteLine(res);
Now let's implement the DeleteFileByPath
Method.
1private static bool DeleteFileByPath(string filePath)2{3 if (File.Exists(filePath))4 File.Delete(filePath);5
6 // Return the confirmation7 return !File.Exists(filePath);8}
Now if we walk through the process again, it will delete the image file from the private file. And if you don't want to delete the photo from the public storage too, just pass the public file path inside the DeleteFileByPath
method like DeleteFileByPath(publicPhotoPath)
.
I hope that this blog helped you in some way. If it did, please share it with your friends. If you want to read the full library documentation, head over to the official GitHub repo.
Thank you.