寧波建設監(jiān)理管理協(xié)會網(wǎng)站營銷的手段和方法
文章目錄
- Camera2介紹
- Camera2的主要API類介紹
- CameraManager
- 通過CameraManage獲取Cameracharacteristics
- 通過CameraManage獲取CameraDevice
- 從CameraDevice獲取CameraCaptureSession
- 預覽效果
- 參考
Camera2介紹
- 從Android 5.0開始,Google 引入了一套全新的相機框架 Camera2(android.hardware.camera2),并且廢棄了舊的相機框架 Camera1(android.hardware.Camera)。
- Camera2相比于Camera的API不僅大幅提高了Android系統(tǒng)拍照的功能,還能支持RAW照片輸出,甚至允許程序調(diào)整相機的對焦模式、曝光模式、快門等。
- Camera2相比于Camera更加靈活的同時,也更加的復雜,包含的類更多。
Camera2的主要API類介紹
Camera2獲取相機涉及的類如下:
CameraManager
攝像頭管理器。這是一個全新的系統(tǒng)管理器,專門用于檢測系統(tǒng)攝像頭、打開系統(tǒng)攝像頭。除此之外,調(diào)用CameraManager的getCameracharacteristics(String)方法即可獲取指定攝像頭的相關特性。代碼如下:
private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT;//后置相機的IDString MyCameraIdStr = Integer.toString(mCameraId);private CameraManager mCameraManager; //相機管理者private CameraCharacteristics mCameraCharacteristics; //相機屬性float EXPOSURE_TIME_RANGE_min_hz = 0, EXPOSURE_TIME_RANGE_max_hz = 0;Range EXPOSURE_TIME_RANGE_msg;//相機曝光時間范圍,不可改變int CameraInfo_FPS_min, CameraInfo_FPS_max;Range[] CameraInfo_FPS_Range;int CameraInfo_ISO_min, CameraInfo_ISO_max;float[] CameraInfo_Aperture;float CameraInfo_Focal_Length[];boolean FlagOfCreate = false;private void CreateCamera() { //獲取CameraManager,得到相機參數(shù)mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);try {mCameraCharacteristics = mCameraManager.getCameraCharacteristics(MyCameraIdStr);Log.d("曝光補償范圍", mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE).toString());//上述語句獲取相機設備支持的曝光補償范圍Log.d("快門時間", mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE).toString());} catch (CameraAccessException e) {e.printStackTrace();}FlagOfCreate = true;EXPOSURE_TIME_RANGE_msg = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);EXPOSURE_TIME_RANGE_max_hz = (float) (1000000000.0 / (long) EXPOSURE_TIME_RANGE_msg.getLower());EXPOSURE_TIME_RANGE_min_hz = (float) (1000000000.0 / (long) EXPOSURE_TIME_RANGE_msg.getUpper());
// Log.d("測試:",String.format("%d",EXPOSURE_TIME_RANGE_msg.getLower()));
// CameraInfo_FPS_min = (Range[])(mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES))CameraInfo_FPS_Range = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);CameraInfo_FPS_min = (int) CameraInfo_FPS_Range[0].getLower();CameraInfo_FPS_max = (int) CameraInfo_FPS_Range[CameraInfo_FPS_Range.length - 1].getUpper();
// for(int i = 0; i < CameraInfo_FPS_Range.length; ++ i)
// {
// Log.d("幀率:",CameraInfo_FPS_Range[i].toString());
// }CameraInfo_ISO_min = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE).getLower();CameraInfo_ISO_max = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE).getUpper();CameraInfo_Aperture = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);CameraInfo_Focal_Length = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
//}public void BtnClick_CameraInfo(View v) {if (FlagOfCreate != true) {CreateCamera();}String msg = "";msg += "快門速度:" + String.format("%.4f,%.4f", EXPOSURE_TIME_RANGE_min_hz, EXPOSURE_TIME_RANGE_max_hz) + "赫茲\n";msg += "相機幀率:" + String.format("%d,%d", CameraInfo_FPS_min, CameraInfo_FPS_max) + " fps\n";msg += "ISO::" + String.format("%d,%d", CameraInfo_ISO_min, CameraInfo_ISO_max) + "\n";msg += "光圈:";for (int i = 0; i < CameraInfo_Aperture.length; ++i) {msg += String.format("%f,", CameraInfo_Aperture[i]);}msg += "\n";msg += "焦距:";for (int i = 0; i < CameraInfo_Focal_Length.length; ++i) {msg += String.format("%f,", CameraInfo_Focal_Length[i]);}msg += "\n";TextMsg.setText(msg);// Log.d("CameraInfo","WCC");}
運行結(jié)果如下:
可以發(fā)現(xiàn)相機的光圈只有一個值,即手機的攝像頭光圈是固定的,只有一個光圈值。
通過CameraManage獲取Cameracharacteristics
攝像頭特性。該對象通過CameraManager來獲取,用于描述特定攝像頭所支持的各種特性。
相比于舊 API 中的 CameraInfo 類。Cameracharacteristics包括:
曝光補償(Exposure compensation)、
自動曝光/自動對焦/自動白平衡模式(AE / AF / AWB mode)、
自動曝光/自動白平衡鎖(AE / AWB lock)、
自動對焦觸發(fā)器(AF trigger)、
拍攝前自動曝光觸發(fā)器(Precapture AE trigger)、
測量區(qū)域(Metering regions)、
閃光燈觸發(fā)器(Flash trigger)、
曝光時間(Exposure time)、
感光度(ISO Sensitivity)、
幀間隔(Frame duration)、
鏡頭對焦距離(Lens focus distance)、
色彩校正矩陣(Color correction matrix)、
JPEG 元數(shù)據(jù)(JPEG metadata)、
色調(diào)映射曲線(Tonemap curve)、
裁剪區(qū)域(Crop region)、
目標 FPS 范圍(Target FPS range)、
拍攝意圖(Capture intent)、
硬件視頻防抖(Video stabilization)等。
在上段的例程中,我們展示了通過CameraManage獲取CameraCharacteristics,并顯示在界面上。
想更詳細地了解相關信息,可以參考:
Android Camera2 之 CameraCharacteristics 詳解
官方介紹鏈接
通過CameraManage獲取CameraDevice
在最上面的流程圖中,CameraManage只是從Context獲取攝像頭,并進行管理,此時我們可以獲取相機的一些參數(shù)。如果想進行拍照獲取圖像,則還需要獲取CameraDevice類對象。
CameraDevice通過CameraManage的openCamera方法在回調(diào)函數(shù)中獲取打開的攝像頭,具體代碼如下:
CameraDevice.StateCallback MyDeviceCallback; //攝像頭監(jiān)聽,在回調(diào)中獲取camera deviceCameraDevice MyCameraDevice;MyDeviceCallback = new CameraDevice.StateCallback() {@Overridepublic void onOpened(@NonNull CameraDevice camera) {//@NonNull后,便會自動對該參數(shù)值進行判空。Log.d("Camera調(diào)試:", "成功獲取Camera Device");MyCameraDevice = camera;takePreview();//獲取Camera device后,從Camera device獲取Capture Session}@Overridepublic void onDisconnected(@NonNull CameraDevice camera) {Log.d("Camera調(diào)試:", "獲取Camera Device失敗");}@Overridepublic void onError(@NonNull CameraDevice camera, int error) {Log.d("Camera調(diào)試:", "獲取Camera Device錯誤");}
};
首先,我們聲明了一個CameraDevice.StateCallback類型的對象,該對象的作用是在執(zhí)行CameraDevice.OpenCamera方法時,將該回調(diào)對象傳進去,執(zhí)行OpenCamera后,會自動地調(diào)用該回調(diào)函數(shù)對象。如下:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {Log.d("相機調(diào)試:", "沒有權限");return;}try {mCameraManager.openCamera(MyCameraIdStr, MyDeviceCallback, null);//打開相機,監(jiān)聽回調(diào),在回調(diào)函數(shù)中獲取camera device} catch (CameraAccessException e) {Log.e("相機錯誤:", "打開攝像頭失敗");}
從CameraDevice獲取CameraCaptureSession
CameraCaptureSession的作用是控制相機進行預覽或者拍照,可以通過CameraDevice的createCaptureSession方法創(chuàng)建,代碼如下:
CameraCaptureSession MyCameraCaptureSession; //由CameraDvice創(chuàng)建,控制攝像頭預覽或拍照List<Surface> surfaces;surfaces = new ArrayList<>();surfaces.add(MySurfaceView.getHolder().getSurface());
try {/** 參數(shù)* outputs 相機流輸出的地方* callback* handler 表示 createCaptureSession 代碼運行所在的線程,傳null,表示運行在當前線程*/MyCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {MyCameraCaptureSession = cameraCaptureSession;Log.d("MyCameraDevice.createCaptureSession:","成功獲取CameraCaptureSession");}@Overridepublic void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {Log.d("MyCameraDevice.createCaptureSession:", "獲取camera capture session錯誤");}
}, null);
} catch (CameraAccessException e) {
Log.e("開啟預覽:", "錯誤,不能訪問攝像頭");
}
其中createCaptureSession的第一個參數(shù)surfaces是指明預覽數(shù)據(jù)流輸出的地方,這里我們從界面上獲取一個SurfaceView,將SurfaceView目前的Surface放入List surfaces,作為形參傳給createCaptureSession,至此,就可以在界面上看到預覽的效果了。
預覽效果
如下圖所示:
參考
android camera2 詳解說明(一)
Camera2 教程 一概覽
Android:Camera2的簡單使用
Camera參考詳述
camera2使用相機