Saturday, July 31, 2010

Live Camera Preview on Android

Android SDK provides a full control on Android devices' hardware, so that you can use any component of your device in your applications. Thanks to this feature, you can use your device's camera to obtain live camera preview in your application. So that, you can build your own camera application with additional features.

Basically in a camera application, you need a camera surface and a button to take photos. First we start with getting required permission for Camera component. Also put a control into the activity tag to keep screen in landscape mode.


 <uses-permission android:name = "android.permission.CAMERA"/>

 <activity .......
    android:screenOrientation="landscape" ...... >


Then we create a simple layout includes a SurfaceView and a Button.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="horizontal"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">

 <SurfaceView
  android:id="@+id/preview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_weight="1">
 </SurfaceView>

 <Button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/buttonTakePhoto"
  android:text="Click"
  android:gravity="center">
 </Button>

</LinearLayout>

Now we are ready to build our application to put the camera preview into our SurfaceView and to set the button's behavior for taking photos. Our activity must implement the SurfaceHolder.Callback interface in order to provide a camera preview.


 // Let's name our Activity as CamDroid.
public class CamDroid extends Activity implements SurfaceHolder.Callback

Then we create our Camera, Surface and Button fields which will be initialized when our activity is started.


    private Camera mCamera;
    private Button takePictureButton;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

After this fields we need to declare which actions will be performed when user takes a photo.


    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera c) {
         
         FileOutputStream outStream = null;
          try {
          
          // Directory and name of the photo. We put system time
          // as a postfix, so all photos will have a unique file name.
          outStream = new FileOutputStream("/sdcard/CamDroid_" +
              System.currentTimeMillis()+".jpg");
          outStream.write(data);
          outStream.close();
          Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
         } catch (FileNotFoundException e) {
          e.printStackTrace();
         } catch (IOException e) {
          e.printStackTrace();
         } finally {
        }

            Log.e(TAG, "PICTURE CALLBACK: data.length = " + data.length);
            mCamera.startPreview();
        }
    };

Now we can implement the onCreate method of the Activity to initialize our surface and Button.


    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);

        // We don't need a title for our camera window.
        // It makes our view smaller.
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        Log.e(TAG, "onCreate");
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        // In my case, name of the layout file is camdroid.xml
        setContentView(R.layout.camdroid);

        // Initialize the surface
        mSurfaceView = (SurfaceView)findViewById(R.id.preview);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        // Initialize the Button
        takePictureButton = (Button)findViewById(R.id.buttonTakePhoto);
        
        // Set the button's behavior
        takePictureButton.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
          mCamera.takePicture(null, null, mPictureCallback);
         }
        });
    }

Then we must provide some methods for our surface to create first preview, change preview, and stop preview.


    // Create camera preview.
    public void surfaceCreated(SurfaceHolder holder)
    {
        Log.e(TAG, "surfaceCreated");
        mCamera = Camera.open();
        //mCamera.startPreview();
    }

    // Change preview's properties (i.e. size or format).
    public void surfaceChanged(SurfaceHolder holder,
          int format, int w, int h)
    {
        Log.e(TAG, "surfaceChanged");

        // XXX stopPreview() will crash if preview is not running
        if (mPreviewRunning) {
            mCamera.stopPreview();
        }

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(w, h);
        mCamera.setParameters(p);
        try {
         mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
        mCamera.startPreview();
        mPreviewRunning = true;
    }

    // Stop the preview.
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        Log.e(TAG, "surfaceDestroyed");
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();
    }

Now we have a basic camera application which has a camera preview and a button on screen. You can start taking photos with your applications by pressing the button on the screen. Or you can add this method to use your device's built-in "OK" Button (Trackpad for HTC, OK Button for Samsungs etc.) for taking photos.


    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return super.onKeyDown(keyCode, event);
        }
 
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            mCamera.takePicture(null, null, mPictureCallback);
            return true;
        }

        return false;
    }

ScreenShot:

Enjoy your new camera applications and take good photos :)

34 comments:

  1. Hi Yasin,
    I hope to bring development, but it's too hard for me (mackerel time and I do not have the basics) but I have some ideas of which you might be interested, the goal is to take a picture urgent and of sufficient quality :

    http://en.androidwiki.com/wiki/SpeedPic

    u can contact me at billybug well on gmail ;-)

    friendly ...
    Billybug.

    ReplyDelete
    Replies
    1. Great Article android based projects

      Java Training in Chennai

      Project Center in Chennai

      Java Training in Chennai

      projects for cse

      The Angular Training covers a wide range of topics including Components, Angular Directives, Angular Services, Pipes, security fundamentals, Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training

      Delete
  2. Is there a complete java file for this? I created a TAG, but I am unaware what to do about "mPreviewRunning." It says mPreviewRunning cannot be resolved to a variable. What do I do about that?

    ReplyDelete
  3. Yeah, there's something missing here. Can this please be updated so the tutorial is complete? Thanks.

    ReplyDelete
  4. @Daniel you should define a boolean mPreviewRunning in your class. That attribute prevents users to try to take photo while previewing the last photo.

    ReplyDelete
  5. Hello Yasin
    thanks for this nice preview
    while the camera is open ,how i can make a digital zoom for the surfacview
    I tred but with no luck ,something like if i have 2 buttons (zoom in ,zoom out) could you please tell me how I could do that
    thanks
    Anas

    ReplyDelete
  6. please just inbox me the full program files so i can just dowload it....
    e mail , limoraka@gmail.com
    thanks

    ReplyDelete
  7. Given so much info in it, These type of articles keeps the users interest in the website, and keep on sharing more .Android Training in velachery | Android Training in chennai | Android Training in chennai with placement

    ReplyDelete
  8. Such a fabulous articles in my job, It's enjoyable posts like easiest understands words of experience in information.
    .Net Training in Chennai | Dot Net Training Institute in Chennai | Best Hadoop Training in Chennai | Selenium Training with Placement in Chennai

    ReplyDelete
  9. keep up the good work. this is an Assam post. this to helpful, i have reading here all post. i am impressed. thank you. this is our digital marketing training center. This is an online certificate course
    digital marketing training in bangalore | https://www.excelr.com/digital-marketing-training-in-bangalore

    ReplyDelete
  10. This article is really helpful for me. I am regular visitor to this blog. Share such kind of article more in future. Personally i like this article a lot and you can have a look at my services also: I was seriously search for a Salesforce training institutes in ameerpet which offer job assistance and Salesforce training institutes in Hyderabad who are providing certification material. It's worth to join Salesforce training institutes in India because of their real time projects material and 24x7 support from customer desk. You can easily find the best Salesforce training institutes in kukatpally kphb which are also a part of Pega training institutes in hyderabad. This is amazing to join Data science training institutes in ameerpet who are quire popular with Selenium training institutes in ameerpet and trending coureses like Java training institutes in ameerpet and data science related programming coures python training institutes in ameerpet If you want HCM course then this workday training institutes in ameerpet is best for you to get job on workday.

    ReplyDelete
  11. Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
    workday studio online training
    best workday studio online training
    top workday studio online training

    ReplyDelete
  12. I've read this post and if I could I desire to suggest you some interesting things or suggestions. Perhaps you could write next articles referring to this article. I want to read more things about it!
    Artificial Intelligence Training in Hyderabad
    Artificial Intelligence Course in Hyderabad

    ReplyDelete
  13. Very nice article. I enjoyed reading your post. very nice share. I want to twit this to my followers. Thanks
    Data Science Training in Hyderabad
    Data Science Course in Hyderabad

    ReplyDelete
  14. It is better to engaged ourselves in activities we like. I liked the post. Thanks for sharing.
    DevOps Training in Hyderabad
    DevOps Course in Hyderabad

    ReplyDelete
  15. Very excellent post!!! Thank you so much for your great content. Keep posting.....

    Python Training Institute in Pune
    Best Python Classes in Pune

    ReplyDelete
  16. Such a very useful article. Very interesting to read this article.
    I would like to thank you for the efforts you had made for writing this awesome article.
    Reactjs Training in Chennai |
    Best Reactjs Training Institute in Chennai |
    Reactjs course in Chennai

    ReplyDelete
  17. When invited to turn out to be OJO A-listers, players get a reimbursement on all bets with limitless payouts. Registered players also obtain day by day kickers, which assist them earn extra rewards and improve in degree the extra they play. Unlocking ranges means extra bonus spins for games and the OJO Wheel, properly as|in addition to} cash prizes and extra. If you’re one of many scores of 바카라사이트 Wildz players who likes to win money on the go, we’ve made each effort to make sure your experience is slick and clean.

    ReplyDelete