Wednesday 25 February 2015

Make Your Own Camera Part-1

Android provides a flexible API to develop your own Camera application. Suppose you want to take picture that is private and don’t want to share with other application. If you take a picture using built-in camera then the picture is automatically added in gallery and gallery is easily accessible by all the apps.  For this purpose you have to make your own camera and you can implement all the features those are there in In-Built camera. This is one of the example to build your own camera. If your application require just to take a picture then you can use the built-in camera.


So, Let us start to build our own camera…….
android.hardware.Camera  is the basic class you need to implement the camera. This class manages all the actions taken by the camera like start/stop preview, snap picture, retrieve frame for video etc.

To use camera hardware you need permission in android manifest.xml.  Likewise you should use the camera autofocus so add the following feature like below one.

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

Next, generally android devices have both front and back camera, so you need the appropriate camera id. Once you get the id, open the camera with the id.

private int getCameraId() {
       int camId = -1;
       int numCameras = Camera.getNumberOfCameras();
       Camera.CameraInfo ci = new Camera.CameraInfo();

       for (int i = 0; i < numCameras; i++) {

           Camera.getCameraInfo(i, ci);
          
           if (ci.facing == Camera.CameraInfo.CAMERA_FACING_BACK)
           // to get front camera
          // if (ci.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
           {
               camId = i;
           }
       }
       return camId;
   }

Once you get the camera id, open the camera using Camera class.
Camera myCamera = Camera.open(id);

Next, camera needs a SurfaceHolder object to display the preview before taking a picture. User must be aware what are things inside the picture. According to documentation SurfaceHolder must be fully initialized. To fulfill this put a SurfaceView inside the Activity layout file.

       <SurfaceView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/camera_surfaceView"
       />

Get SurfaceHolder from SurfaceView inside your activity onCreate method and set that to the camera. These code can be placed inside your onStart method.

SurfaceView surfaceView = (SurfaceView)findViewById(R.id.camera_surfaceView);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
camera.setPreviewDisplay(surfaceHolder);

Now your camera is initialized, you need to start the preview to see the things what camera sees. This is event so you can use a button click or simply put this inside onResume method to start the preview as soon as you launch the activity.

camera.startPreview();

Next, to take the picture, call takePicture method. It needs at least three parameters, only one is essential to gather picture. The essential parameter is Camera.PictureCallback object. This callback is used to store the final picture to a file and persist this to the disk. You must add a button like thing inside your activity layout to trigger the image capture event.
camera.takePicture(null, null, pictureCallback);

private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
       @Override
       public void onPictureTaken(byte[] data, Camera camera) {

           File pictureFile = getImageMediaFile();
          
           try {              
               FileOutputStream fos = new FileOutputStream(pictureFile);
               fos.write(data);
               fos.close();
           } catch (Exception e) {
               Log.i(TAG, "File not found: " + e.getMessage());
           }
           // remember to release the camera
           camera.release();
           Log.i(TAG,"Camera is released");
       }
   };    


private File getImageMediaFile() {

       File pictureDirectory = new File(Environment.getExternalStorageDirectory(),"MyCamera");
       if(!ALF_HOME_DIRECTORY.exists()){
           if(!ALF_HOME_DIRECTORY.mkdir()){
               Log.i(TAG,"Home Directory does not Exists");
           }
       }

       String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
       File picture = new File(pictureDirectory.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
       Log.i(TAG, "mediaFile: " + picture);
       return picture;
   }

Note: Please release the camera after taking the picture. It is sharable hardware resource and an important one. If you do not release the camera then even built-in camera will not work. So most often you should release the camera in onStop activity life cycle method or immediately after the image capture by calling inside the PictureCallback instance.

In the next post, You will get the full source code…….

No comments:

Post a Comment