Android拍照

我叫阿狸貓發表於2014-04-08

1.配置許可權

<uses-feature android:name="android.hardware.camera" /><!-- 照相機硬體裝置特性 -->
<uses-permission android:name="android.permission.CAMERA" /><!-- 照相機許可權 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 寫到外儲存裝置許可權(寫到SD卡) -->

2.在佈局檔案中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.image.MainActivity"
    tools:ignore="MergeRootFrame" 
    android:orientation="vertical">

    <!-- 建立出來的預覽類新增到FrameLayout裡,這裡是因為祕密拍攝,將寬高設定成1dp -->
    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="1dp"
        android:layout_height="1dp"/>
    <Button 
        android:onClick="takePicture"
        android:text="拍照"
        android:layout_width="wrap_content"
    	android:layout_height="wrap_content"/>
</LinearLayout>
3.建立照相機畫面預覽類

/**
 * 照相機畫面預覽類
 * @author Administrator
 *
 */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "CameraPreview";
	private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // 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) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }
    //預覽介面銷燬的時候執行
    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }
    //預覽介面旋轉改變方向的時候執行
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}
4.MainActivity

import java.io.File;
import java.io.FileOutputStream;

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.widget.FrameLayout;

public class MainActivity extends Activity {
	private Camera mCamera;
	private CameraPreview mPreview;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		//1.獲取照相機例項
		mCamera = getCameraInstance();

		//2.獲取照相機預覽類
		mPreview = new CameraPreview(this, mCamera);
		FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
		preview.addView(mPreview);//3.將照相機的預覽介面加入到指定的FrameLayout裡
	}

	//當點選按鈕的時候進行拍照
	public void takePicture(View view){
		mCamera.autoFocus(null);//自動對焦,引數是個自動對焦完畢後的回撥函式(一般是在這個回撥函式裡拍照)
		/**
		 * 1.引數一:按下快門的時候的回撥函式(一般是呼叫快門聲音)
		 * 2.引數二:當相機獲取原始照片時觸發該監聽器
		 * 3.引數三:當相機獲取JPG照片時觸發該監聽器
		 */
		mCamera.takePicture(null, null, mPicture);
	}
	
	/**
	 * 獲取一個照相機例項
	 * @return
	 */
	public static Camera getCameraInstance() {
		Camera c = null;
		try {
			c = Camera.open(0); // 獲取後置攝像頭 open(1)前置 open(0)和open()都是後置
		} catch (Exception e) {
			// Camera is not available (in use or does not exist)
		}
		return c; // returns null if camera is unavailable
	}
	
	
	private PictureCallback mPicture = new PictureCallback() {

	    private String TAG = "MainActivity";

		@Override
	    public void onPictureTaken(byte[] data, Camera camera) {

	        File pictureFile = new File(Environment.getExternalStorageDirectory(),"123.jpg");
	        try {
	            FileOutputStream fos = new FileOutputStream(pictureFile);
	            fos.write(data);
	            fos.close();
	        } catch (Exception e) {
	            Log.d(TAG, "Error accessing file: " + e.getMessage());
	        }
	    }
	};
	
	protected void onDestroy() {
		super.onDestroy();
		if(mCamera!=null){
			mCamera.stopPreview();//停止預覽
			mCamera.release();//釋放資源
			mCamera = null;
		}
	};
}





相關文章