Thursday, December 30, 2010

Implement takePicture function of Android Camera

In order to implement takePicture function of Android Camera, we have to implement ShutterCallback, PictureCallback for RAW and PictureCallback for JPG. To take picture, simple call camera.takePicture() method passing with the Callbacks.

takePicture

Modify from the last exercise "Add a overlay on Camera Preview SurfaceView". Modify AndroidCamera.java
package com.exercise.AndroidCamera;

import java.io.IOException;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;

public class AndroidCamera extends Activity implements SurfaceHolder.Callback{

Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);

Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}});
}

ShutterCallback myShutterCallback = new ShutterCallback(){

@Override
public void onShutter() {
// TODO Auto-generated method stub

}};

PictureCallback myPictureCallback_RAW = new PictureCallback(){

@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub

}};

PictureCallback myPictureCallback_JPG = new PictureCallback(){

@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
}};

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}

if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}


Download the files.

next:
- Save the camera image using MediaStore



7 comments:

Bill Soriano said...

Hi
Excellent tutorial, thanks for sharing your knowledge, I have a
query ... I add an opaque background and an image on the view (macro)...but when I
take a photo not recorded...this is the image http://dl.dropbox.com/u/46059390/fotos/imageOverlayAndroid.JPG
the upper image is in main.xml and the other in the same control.xml ...have any idea how to do this

Areyes said...

Hello....
A very nice tutorial, I've try to folow your tutorial, and it's all are working well... Thanks

I have one question, how if i want to "take picture" automaticaly and countinously without button.... I mean, use timer or anything else...
Do you have any idea ?

Thank you :)

Anonymous said...

i got error for control cannot be resolved
for the code statment
controlInflater.inflate(R.layout.cont
rol, null);

Unknown said...

Hello, when I push the botton the app crash. Maybe the code to take the picture is not invocated, help please.

Unknown said...

Hi,
I dont have errors in my code, but when I want take a picture the app crash, maybe it appear for the method that is not invocate for the button. how can inflate the button's method?

Anonymous said...

in this project add


to manifest.

Carlos said...

Hello friend, as would do if I want to add a layout to your photo taken, would use another layer or there is any property or method that you can add to the picture, thanks for your answer.