2012/08/07

How to use camera in Android?

This article teaches how to use Android camera.

Step1:Camera preview needs a surface to show.And needs some callback function to handle the take picture processes.
We create a class named CameraPreivew, and implement the SurfaceHolder.Callback and CameraPreviewCallback.
public class CameraPreview implements SurfaceHolder.Callback, Camera.PreviewCallback
{
 public CameraPreview(int PreviewlayoutWidth, int PreviewlayoutHeight)
 {
  // TODO
 } 
 @Override
 public void onPreviewFrame(byte[] arg0, Camera arg1) 
 {
  // At preview mode, the frame data will push to here.
  // But we do not want these data.
 }

 @Override
 public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) 
 {
  // TODO Auto-generated method stub
 }

 @Override
 public void surfaceCreated(SurfaceHolder arg0) 
 {
  // TODO Auto-generated method stub
 }

 @Override
 public void surfaceDestroyed(SurfaceHolder arg0) 
 {
  // TODO Auto-generated method stub
 }

 // Take picture interface
 public void CameraTakePicture(String FileName)
 {
  // TODO 
 }
 
 // Set auto-focus interface
 public void CameraStartAutoFocus()
 {
  // TODO 
 }
}
Step2: At the class constructor, we set the preview size.
 
public CameraPreview(int PreviewlayoutWidth, int PreviewlayoutHeight)
{
 PreviewSizeWidth = PreviewlayoutWidth;
 PreviewSizeHeight = PreviewlayoutHeight;
}
Step3:At the SurfaceHolder callback functions, we handle the camera instance.
 
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) 
{
  Parameters parameters;
  mSurfHolder = arg0;
  
  parameters = mCamera.getParameters();
  // Set the camera preview size
  parameters.setPreviewSize(PreviewSizeWidth, PreviewSizeHeight);
  // Set the take picture size, you can set the large size of the camera supported.
  parameters.setPictureSize(PreviewSizeWidth, PreviewSizeHeight);
  
  // Turn on the camera flash. 
  String NowFlashMode = parameters.getFlashMode();
  if ( NowFlashMode != null )
   parameters.setFlashMode(Parameters.FLASH_MODE_ON);
  // Set the auto-focus. 
  String NowFocusMode = parameters.getFocusMode ();
  if ( NowFocusMode != null )
   parameters.setFocusMode("auto");
  
  mCamera.setParameters(parameters);
  
  mCamera.startPreview();
}

@Override
public void surfaceCreated(SurfaceHolder arg0) 
{
 mCamera = Camera.open();
 try
 {
  // If did not set the SurfaceHolder, the preview area will be black.
  mCamera.setPreviewDisplay(arg0);
  mCamera.setPreviewCallback(this);
 } 
 catch (IOException e)
 {
  mCamera.release();
  mCamera = null;
 }
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) 
{
 mCamera.setPreviewCallback(null);
 mCamera.stopPreview();
 mCamera.release();
 mCamera = null;
}
Step4:In the PreviewCallback, we call the myAutoFocusCallback to handle the take picture processes after the auto-focus.
 
// Take picture interface
public void CameraTakePicture(String FileName)
{
 TakePicture = true;
 NowPictureFileName = FileName;
 mCamera.autoFocus(myAutoFocusCallback);
}
 
// Set auto-focus interface
public void CameraStartAutoFocus()
{
 TakePicture = false;
 mCamera.autoFocus(myAutoFocusCallback);
}

Step5:Create a instance to implement the AutoFocusCallback.
 
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback()
{
 public void onAutoFocus(boolean arg0, Camera NowCamera) 
 {
  if ( TakePicture )
  {
   NowCamera.stopPreview();//fixed for Samsung S2
   NowCamera.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);
   TakePicture = false;
  }
 }
};

Step6:Implement 3 callback instance to handle the takepicture processes.
 
ShutterCallback shutterCallback = new ShutterCallback()
{
 public void onShutter() 
 {
  // Just do nothing.
 }
};
   
PictureCallback rawPictureCallback = new PictureCallback()
{
 public void onPictureTaken(byte[] arg0, Camera arg1) 
 {
  // Just do nothing.
 }
};
   
PictureCallback jpegPictureCallback = new PictureCallback()
{
 public void onPictureTaken(byte[] data, Camera arg1) 
 {
  // Save the picture.
  try {
   Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,data.length);
   FileOutputStream out = new FileOutputStream(NowPictureFileName);
   bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
  } 
  catch (IOException e) 
  {
   e.printStackTrace();
  }
 }
}; 

Step7:The camera basic function we all implemented, now we go back to the main activity to use the CameraPreview.
 
public class MyCamera extends Activity
{
 private CameraPreview camPreview; 
 private FrameLayout mainLayout;
     
 private Handler mHandler = new Handler(Looper.getMainLooper());
 
 @Override
 public void onCreate(Bundle savedInstanceState) 
 {
  super.onCreate(savedInstanceState);
  //Set this SPK Full screen
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  WindowManager.LayoutParams.FLAG_FULLSCREEN);
  //Set this APK no title
  requestWindowFeature(Window.FEATURE_NO_TITLE);  
  setContentView(R.layout.main);
        
  SurfaceView camView = new SurfaceView(this);
  SurfaceHolder camHolder = camView.getHolder();
  camPreview = new CameraPreview(640, 480);
        
  camHolder.addCallback(camPreview);
  camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
  mainLayout = (FrameLayout) findViewById(R.id.frameLayout1);
  mainLayout.addView(camView, new LayoutParams(640, 480));
 }

 @Override 
 public boolean onTouchEvent(MotionEvent event) 
 { 
  if (event.getAction() == MotionEvent.ACTION_DOWN) 
  { 
   int X = (int)event.getX(); 
   if ( X >= 640 )
    mHandler.postDelayed(TakePicture, 300);
   else
    camPreview.CameraStartAutoFocus();
  }
  return true;
 };
    
 private Runnable TakePicture = new Runnable() 
 {
  String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
  String MyDirectory_path = extStorageDirectory;
  String PictureFileName;
  public void run() 
  {
   File file = new File(MyDirectory_path);
   if (!file.exists()) 
    file.mkdirs();
   PictureFileName = MyDirectory_path + "/MyPicture.jpg";
   camPreview.CameraTakePicture(PictureFileName);
 }
 };    
}

Step8:The code is all done here, now is to setup the Android configuration to active the Camera hardware.Edit AndroidManifest.xml to active the function we need.
 


    
      
 
    
 
 
 

    
        
            
                
                
            
        

    


Step9:And the layout file main.xml should be simple like this.
 





10 comments:

  1. Hey, thanks for the tutorial!
    Is there somewhere a complete version with both files? I don't understand where the code of the steps 5 and 6 has to be written down!?
    I hope you can help me understanding it better :)

    ReplyDelete
    Replies
    1. hi FaGo:

      I submit tje project to GitHub.
      https://github.com/ikkiChung/MyCamera

      Delete
  2. These code should be in the class CameraPreview. These callback function take care the take picture processes.

    ReplyDelete
  3. Hey - thanks for posting this, and please forgive the stupid questions, I'm pretty new at this...couple things:
    #1) I'm trying to use the device camera as the entire background of my window, but the highest I can set the resolution with a slew of errors is 640x480. When I bump it up to the actual resolution of the device (800x480) everything goes to hell and there are errors with the Camera.setParameters lines, but I can't step into that method to see what's wrong.

    #2) This may just be because the code above isn't really complete, but when I do successfully take a picture at the lower resolution, the device locks up and the flashlight stays on even after the ADK has been disconnected. Not sure if this is an issue with file saving or what. Every time I try to debug it gives me an error and fails before running.

    Any thoughts on what I might be doing wrong? I'm running/debugging on an HTC incredible with Android 2.3.4.

    ReplyDelete
    Replies
    1. #1) Maybe you can use Camera.getParameters() to get the support size of your camera.

      2#) This situation might happen in different hardware.
      In my code i add this line
      NowCamera.stopPreview();//fixed for Samsung S2
      So you can try another way.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This might be off topic but how do I merge color blob detection with camera in taking pictures ? Im seem to be having some trouble with CameraBridgeViewBase and JavaCameraView

    ReplyDelete