android通過camera和surfaceview選擇攝像頭並即時預覽
阿新 • • 發佈:2019-01-24
在使用android裝置的攝像頭的時候我們有兩種選擇:
1.呼叫intent方法使用攝像頭
2.通過camera類使用攝像頭
第一種方法非常方便,不過需要跳到新的activity中,這樣的使用者體驗並不是特別好
使用camera能有更大的自定義空間!
使用camera就需要用surfaceview顯示攝像頭的即時畫面
我們這樣設定layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context="com.example.video_activity.MainActivity" > <SurfaceView android:id="@+id/surfaceview" android:layout_width="320dp" android:layout_height="240dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" > <Button android:id="@+id/change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="change" /> </LinearLayout> <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="which camera" /> </LinearLayout>
一個靜態的surfaceview、Button和Textview
button是用於後面切換攝像頭的
textview用於顯示攝像頭id
例項化以上控制元件再宣告一個camera物件。
private Camera mCamera;
例項化控制元件後還要給surfaceview一個holder用於接收camera的內容。
一個layoutParameters用於改變surfaceview尺寸(否則會產生畸變)
lp = surfaceView.getLayoutParams();
sh = surfaceView.getHolder();
選一個攝像頭的id(預設可以為0或者1),獲取它的資訊
private Void OpenCameraAndSetSurfaceviewSize(int cameraId) { mCamera = Camera.open(cameraId);//id用於選中不同的攝像頭,有的相機會有很多的 Camera.Parameters parameters = mCamera.getParameters(); Size pre_size = parameters.getPreviewSize(); Size pic_size = parameters.getPictureSize();//和預覽的尺寸不同,這是拍照後實際相片的尺寸,會比較大 android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info);//獲取選中的攝像頭資訊 int camera_number = Camera.getNumberOfCameras();//獲取攝像頭數量 if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {//分辨是否前置攝像頭 textview.setText("There are " + camera_number + " camera." + "This is the Front Camera!"); } else { textview.setText("There are " + camera_number + " camera." + "This is the Back Camera!"); } lp.height = pre_size.width * 2; lp.width = pre_size.height * 2; return null; }
我們編寫SetAndStartPreview方法例項化camera並將預覽載入到surfaceview中
private Void SetAndStartPreview(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
切換攝像頭的原理就將camera釋放掉再重新載入。
為button新增事件監聽:change_Button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.stopPreview();
mCamera.release();
if (cameraId == 0) {
cameraId = 1;
} else {
cameraId = 0;
}
OpenCameraAndSetSurfaceviewSize(cameraId);
// the surfaceview is ready after the first launch
SetAndStartPreview(sh);
}
});
值得一提的是我們將camera和surface holder關聯的時候必須確保surfaceview已經建立好,否則camera獲取不到surfaceview的資訊
我們需要為surfaceholder新增addCallback(this);並在create中呼叫方法
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
SetAndStartPreview(holder);
}
原始碼在這裡⬇️
http://download.csdn.net/detail/edwardwayne/8491597