Capture Image from Camera
To start with, we will open Visual Studio and follow the below steps –
• Click File > New > Project to start a new project.
• Select Android from the left tree and then select “Android Application” template
from the right. Type in a name for the project as “AndroidCameraVS” and hit OK
or press “Enter”.
• As soon as the project is created with this template, you will see a lot of files
and folders created with the template.
• To enable the app to use the camera, we first need to set the App capabilities
and permissions to use the Camera. For this, we Double-click on Properties in
the Solution Explorer and select the Android Manifest tab in the Properties window.
• Check the “Camera” checkbox from the Required Permissions list and save the manifest
file. This will automatically create entries in your manifest file to allow the
app to access the camera.
• Add an ImageView Control to Main.axml file below the default button to hold the
captured image. This control will be used to display the captured image by the
camera.
<ImageView
android:src="@android:drawable/ic_menu_gallery"
android:layout_width="fill_parent"
android:layout_height="300.0dp"
android:id="@+id/imageView1"
android:adjustViewBounds="true" />
• Change the value of “Hello” key in string.xml to “Open Camera” so that our app
looks a bit clear on what it does ?
• Add the below references to the top of Activity1.cs file
using System.Collections.Generic;
using Android.Content.PM;
using Android.Net;
using Android.Graphics;
• Add 2 objects of Java.IO.File class for referencing the file and directory in your
app. Also, add an ImageView object to refer the ImageView control present in
Main.axml file.
Java.IO.File _file;
Java.IO.File _dir;
ImageView _imageView;
• Next thing is to update the Activity.cs file’s OnCreate(). Copy the below code
and paste in your Activity1.cs file. I will explain each line below the code.
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
if (IsThereAnAppToTakePictures())
{
CreateDirectoryForPictures();
Button button = FindViewById<Button>(Resource.Id.myButton);
_imageView = FindViewById<ImageView>(Resource.Id.imageView1);
button.Click += TakeAPicture;
}
}
• The 1st 2 lines of the function initializes the activity and sets the layout of
the activity to controls defined in Main.axml file located at Resources\Layout
folder. Then we define a function that will check whether the app is running
on a device which has an app (an intent as it is technically referred in Xamarin’s
language) to capture picture. If the app exists, we ensure the storage is ready
for storing the pictures. After the folders are created, we get the references
of the button and imageview control in our activity and assign an event handler
to the button to take a picture. Let us know understand each function in detail
below –
• Check whether an image capture intent exists on the device the app is running – The below function will interact with the device hardware and return a Boolean
depending on whether the camera is accessible on the device. We use the PackageManager class to check that the camera is available by passing an object of Intent class with the ActionImageCapture action as the parameter. QueryIntentActivities() of PackageManager class resturns a list of available activities in the device.
If the returned list is not null and the count of element is greater than zero,
it symbolizes that the device has a camera to capture images from.
private bool IsThereAnAppToTakePictures()
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
IList<ResolveInfo> availableActivities = PackageManager.QueryIntentActivities(intent,
PackageInfoFlags.MatchDefaultOnly);
return availableActivities != null && availableActivities.Count > 0;
}
• Ensure proper folders are created – Once the app confirms of the existence of camera in the device, we ensure proper
folders exist in the device memory where we will store our captured images. For
this we have defined the below function. We try to get a reference of the folder
named “AndroidCameraVSDemo” in the device’s default Pictures folder. If it does
not exist, we create a folder using the same name.
private void CreateDirectoryForPictures()
{
_dir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures),
"AndroidCameraVSDemo");
if (!_dir.Exists())
{
_dir.Mkdirs();
}
}
• Launch the Camera - Once everything is setup, we’re ready to launch the camera and capture an image.
We have already added the “TakeAPicture” event handler to the button on creation
of the activity. We define an intent to use the ActionImageCapture action to
tell the camera to return an image from the camera. In case you want to return
the video, you can use MediaStore.ActionVideoCapture action for the intent. After
getting the intent, we define a filename with which the captured image will be
saved as. Then we tell the intent to store the output (captured image) to the
file by calling the PutExtra() method of the intent. The final step is to launch
the intent by calling StartActivityForResult() by passing the intent and a request
code. This request code will be available once the activity exits.
private void TakeAPicture(object sender, EventArgs eventArgs)
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
_file = new Java.IO.File(_dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid()));
intent.PutExtra(MediaStore.ExtraOutput, Android.Net.Uri.FromFile(_file));
StartActivityForResult(intent, 0);
}
• Handle Camera Events – Once the camera is launched the user can use it according to his/her choice. As
soon as an image is captured, Android calls an OnActivityResult() in our activity.
We call the base OnActivityResult() to handle the data received by the camera.
This event will allow the app to store the image at user-defined location and
do some task with the just captured image. We check for the user input for the
camera and ensure the user captured the image and not cancelled the camera operation.
The first thing that we do with the captured image is to store the image in our
directory. For this we get the scanned image in MediaScannerScanFile intent and
save the intent data to the file. Once the image is stored the image becomes
available in the device image gallery. After saving the image in gallery, we
resize the image using LoadAndResizeBitamp extenstion written in the code and
assign it to our ImageView control for display. The resizing is done to ensure
less memory is consumed by the app and the app does not crash when used in LIVE
environment.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Canceled) return;
// make it available in the gallery
Intent mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
if (_file != null)
{
Android.Net.Uri contentUri = Android.Net.Uri.FromFile(_file);
mediaScanIntent.SetData(contentUri);
SendBroadcast(mediaScanIntent);
// display in ImageView. We will resize the bitmap to fit the display
// Loading the full sized image will consume to much memory
// and cause the application to crash.
int height = _imgView.Height;
int width = Resources.DisplayMetrics.WidthPixels;
using (Bitmap bitmap = _file.Path.LoadAndResizeBitmap(width, height))
{
_imgView.SetImageBitmap(bitmap);
}
}
}
Once you compile the project and run, you will see the Android emulator will start
and the app will be auto-deployed to your emulator. Once deployed, the application
will look like as below-
After you click on the button, the camera opens and you can take the picture. You
can then see the image in your Gallery as below. Image captured via emulator.
Here you notice the AndroidCameraVSdemo folder that has been created by the app and
inside the folder we have an image!
Source Code: AndroidCameraVS.zip
Hope you like this article.Cheers!