Android cameraSeries Development (III): Taking photos through cameraapi
Author: Rain csdn blog: http://blog.csdn.net/gobitan/
Overview
There are two ways to use camera: using an existing app through intent and building your own app through camera. The intent method has been introduced in Series 1 of development. This article describes how to take photos through cameraapi.
Key classes
Several key classes need to be introduced for taking photos using cameraapi:
Camera class:The main class used to manage camera devices. This article mainly uses the following methods:
- Open (): Obtain the camera instance through the open method.
- Setpreviewdisplay (surfaceholder): sets the preview image.
- Startpreview (): Start Preview
- Stoppreview (): Stop Preview
- Release (): release a camera instance
- Takepicture (camera. shuttercallback shutter, camera. picturecallback raw, camera. picturecallback JPEG): This is the method to be taken and contains three callback parameters. Shutter refers to the callback when the shutter is pressed, raw refers to the callback for obtaining the original data of the photo, and JPEG refers to obtaining the image data compressed into JPG format. The last callback must be implemented in this article. See the following.
Camera. picturecallbackInterface:This callback Interface contains an onpicturetaken (byte [] data, camera) method. You can save image data in this method.
Surfaceview class:Used to control the preview Interface
Surfaceholder. Callback Interface: To process preview events, you must implement the following three methods:
Surfacecreated (surfaceholderholder): This is called when the preview interface is created. It is re-created after each interface change. You need to obtain camera resources and set surfaceholder.
Surfacechanged (surfaceholderholder, int format, int width, int height): this parameter is called when the preview interface changes. You need to restart preview after each interface change.
Surfacedestroyed (surfaceholderholder): called when previewing and destruction, stop previewing and release corresponding resources.
Use the camera method to take photos
The camera method provides richer functions than the intent method. To create a custom camera, follow these steps:
(1) Get the camera instance through camera. open.
(2) To create a preview class, you must inherit the surfaceview class and implement the surfaceholder. Callback interface.
(3) set preview for the camera
(4) construct a preview layout to preview the camera;
(5) create a listener for the photo to obtain the callback after the photo is taken;
(6) Take a photo and save the file;
(7) Release camera.
Procedure
Step 1: Create an android project named androidcamera in eclipse. For more information, see the helloworld example;
Step 2: Add camera-related declarations in androidmanifest. XML as follows:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Step 3: Compile the androidcameraactivity class. The source code of the class is as follows:
import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import android.app.Activity;import android.hardware.Camera;import android.hardware.Camera.PictureCallback;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.FrameLayout;public class AndroidCameraActivity extends Activity implements OnClickListener, PictureCallback { private CameraSurfacePreview mCameraSurPreview = null; private Button mCaptureButton = null; private String TAG = "Dennis"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create our Preview view and set it as the content of our activity. FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); mCameraSurPreview = new CameraSurfacePreview(this); preview.addView(mCameraSurPreview); // Add a listener to the Capture button mCaptureButton = (Button) findViewById(R.id.button_capture); mCaptureButton.setOnClickListener(this); } @Override public void onPictureTaken(byte[] data, Camera camera) { //save the picture to sdcard File pictureFile = getOutputMediaFile(); if (pictureFile == null){ Log.d(TAG, "Error creating media file, check storage permissions: "); return; } try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " + e.getMessage()); } catch (IOException e) { Log.d(TAG, "Error accessing file: " + e.getMessage()); } // Restart the preview and re-enable the shutter button so that we can take another picture camera.startPreview(); //See if need to enable or not mCaptureButton.setEnabled(true); } @Override public void onClick(View v) { mCaptureButton.setEnabled(false); // get an image from the camera mCameraSurPreview.takePicture(this); } private File getOutputMediaFile(){ //get the mobile Pictures directory File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); //get the current time String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); return new File(picDir.getPath() + File.separator + "IMAGE_"+ timeStamp + ".jpg"); }}
Step 4: Added the camerasurfacepreview class. The source code is as follows:
import java.io.IOException;import android.content.Context;import android.hardware.Camera;import android.hardware.Camera.PictureCallback;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;public class CameraSurfacePreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public CameraSurfacePreview(Context context) { super(context); // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on Android versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { Log.d("Dennis", "surfaceCreated() is called"); try {// Open the Camera in preview modemCamera = Camera.open();mCamera.setPreviewDisplay(holder); } catch (IOException e) { Log.d("Dennis", "Error setting camera preview: " + e.getMessage()); } } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Log.d("Dennis", "surfaceChanged() is called"); try { mCamera.startPreview(); } catch (Exception e){ Log.d("Dennis", "Error starting camera preview: " + e.getMessage()); } } public void surfaceDestroyed(SurfaceHolder holder) { if (mCamera != null) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } Log.d("Dennis", "surfaceDestroyed() is called"); } public void takePicture(PictureCallback imageCallback) {mCamera.takePicture(null, null, imageCallback);}}
Step 5:Replace the layout file with the following content:
<?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" > <FrameLayout android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> <Button android:id="@+id/button_capture" android:text="Capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /></LinearLayout>
Step 6:Add the following attributes to the acitvity in androidmanifest. xml:
Android: screenorientation = "Landscape"
Step 7: Run the program.
After taking the photo, you can find the saved photo in the pictures directory of the SD card.
Source code: https://github.com/dennishucd/DennisTech/blob/master/archives/AndroidCamera_20130821.zip
References
1.
Http://developer.android.com/training/camera/videobasics.html
2.
Http://developer.android.com/guide/topics/media/camera.html
3. http://developer.android.com/reference/android/hardware/Camera.html