Creating a Camera Application

[article] [edit page] [discussion] [history]

From Humanitarian-FOSS Project Development Site

´╗┐There are a few concepts that would be helpful in starting to make the camera interface. In general, to make any such application, we need to find the specific programming through which the device is exposed to us.

  • It is CameraDevice class in Android. Various parameters can be passed to the CameraDevice to customize how the picture is taken.
  • The output should be projected on some sort of View Class, which is provided by SurfaceView, an extension of the View class.
  • Saving the file to the file system uses an OutputStream to create the required files in the system. JPG and PNG are allowed. The image quality needs to be assigned at the time though.

Contents

Starting out

Create a new Project in Eclipse titled "MyCamera". Follow the instructions at Creating a project in Eclipse for Android. Select the MyCamera.java file and copy the text of [1] into it. Another method: look into the Graphics section of your android_installation_directory/samples for the same file. Change the class name from CameraPreview to MyCamera. Remember to change the package name to org.hfoss.MyCamera Test 1: You should be able to see the moving box in front of the checkered background.

Understanding the code

It is necessary to understand the code here.

  • Open up the eclipse outline view from Window>Show View>Outline. You should be able to see that

there are two classes defined here. MyCamera and Preview; Preview being the subclass of MyCamera here.

  • Expand Preview. You should be able to see PreviewThread class here. Take a look at the following method.

public void run() {
           // We first open the CameraDevice and configure it.
           CameraDevice camera = CameraDevice.open();
           if (camera != null) {
               CameraDevice.CaptureParams param = new CameraDevice.CaptureParams();
                   param.type = 1; // preview
                   param.srcWidth      = 1280;
                   param.srcHeight     = 960;
                   param.leftPixel     = 0;
                   param.topPixel      = 0;
                   param.outputWidth   = 320;
                   param.outputHeight  = 240;
                   param.dataFormat    = 2; // RGB_565
               camera.setCaptureParams(param);
           }
           // This is our main acquisition thread's loop, we go until
           // asked to quit.
           SurfaceHolder holder = mHolder;
           while (!mDone) {
               // Lock the surface, this returns a Canvas that can
               // be used to render into.
               Canvas canvas = holder.lockCanvas();
               // Capture directly into the Surface
               if (camera != null) {
                   camera.capture(canvas);
               }
               
               // And finally unlock and post the surface.
               holder.unlockCanvasAndPost(canvas);
           }
           // Make sure to release the CameraDevice
           if (camera != null)
               camera.close();
       }

The CameraDevice class is used to open the camera driver, set image parameters and to capture a preview frame or full resolution image (Currently 1280*1024 pixels). Calling the open() static class will return a CameraDevice object. For more detailed information, see CameraDevice Documentation

The following code in Preview installs a SurfaceHolder.Callback to notify for any changes in the surface. {

       mHolder = getHolder();
       mHolder.addCallback(this);

}

In line 156:161 in the code, you'd find this code(Hint: use Ctrl+L in eclipse) which gets a Canvas object from the SurfaceHolder and captures the image from the camera. Then the camera device is closed and the surface is posted.

Modifications

To save a file, we need to make a new Canvas. Unlike the SurfaceView one, it wont be displayed on the screen but it will point to a Bitmap object that will be saved to the device. Copy the following code to the file: private void takePicture() { if (camera != null) { camera.setCaptureParams(param); Bitmap myPic = Bitmap.createBitmap(param.outputWidth, param.outputHeight, false); Canvas canvas = new Canvas(myPic); camera.capture(canvas);

try { OutputStream outStream = this.openFileOutput("pic" + count + ".png", Context.MODE_WORLD_READABLE); myPic.compress(Bitmap.CompressFormat.PNG, 100, outStream); outStream.close(); } catch (IOException e) { Log.e(TAG, e.toString()); } camera.close(); } else { Log.e(TAG, "Failed to open camera device"); return; } } Here, we take the same approach that the thread takes in displaying the picture but instead of displaying it to a screen object we are saving it into a Bitmap and then to a file using the OutputStream.

Runnable methods

Whenever we design a dynamic application like this, especially something that deals with hardware(I/O) and we want our application be robust during the transaction, we run these objects as threads. Android provides the Runnable class for this where a Runnable Object is declared with the threads that need to be run. Hence, we declare a mTakePicture object with the following actions, first we want to pause the preview, take the picture and resume. final Runnable mTakePicture = new Runnable() { public void run() { mPreview.pause(); takePicture(); mPreview.resume(); } };

Listening to KeyStrokes

We need to have some way to Listen for user interactivity. For this, we need to add a onKeyDown method. Right Click anywhere in eclipse editor and select Source>Override/Implement methods ... Type onKeyDown, until public boolean onKeyDown(int, KeyEvent). Click the checkbox and click the ok button, the new overriden method should be added there.

We detect key events in android by comparing the key Codes supplied to the onKeyDown method. The code goes like this: switch (keyCode) {

case KeyEvent.KEYCODE_DPAD_CENTER:
    mPreview.post(mTakePicture);
    break;
 case KeyEvent.KEYCODE_BACK:
    finish();
    break;

} return false; Here mPreview.post() method adds the Runnable object in the queue of the activity to be run. It runs the Runnable function declared in the earlier step which saves the files to the file system.

Test2: To check if your file is saved. To check if your file is actually saved, open the DDMS perspective in eclipse. Click the button beside [Java] button at the top right (tooltip: Open Perspective), below the menu bar. If you don't see DDMS there, select Other and select DDMS from the dialog box to use the DDMS perspective. You can also use Window>Open Perspective to accomplish the same task.

Now, check if your file Explorer view is open, with data, system and tmp folders showing. That's the view of the root folder. Now, go to data/data/org.hfoss.camera/files to get your file. To see the file, select the "pull file from the device icon" at the top right of the file Explorer view and save it to your desired location.

Personal tools