真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

AndroidCamera2預(yù)覽功能實(shí)現(xiàn)

1. 概述

創(chuàng)新互聯(lián)建站是一家專(zhuān)注于成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),商洛網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:商洛等地區(qū)。商洛做網(wǎng)站價(jià)格咨詢(xún):028-86922220

最近在做一些關(guān)于人臉識(shí)別的項(xiàng)目,需要用到 Android 相機(jī)的預(yù)覽功能。網(wǎng)上查閱相關(guān)資料后,發(fā)現(xiàn) Android 5.0 及以后的版本中,原有的 Camera API 已經(jīng)被 Camera2 API 所取代。

全新的 Camera2 在 Camera 的基礎(chǔ)上進(jìn)行了改造,大幅提升了 Android 系統(tǒng)的拍照功能。它通過(guò)以下幾個(gè)類(lèi)與方法來(lái)實(shí)現(xiàn)相機(jī)預(yù)覽時(shí)的工作過(guò)程:

?CameraManager :攝像頭管理器,主要用于檢測(cè)系統(tǒng)攝像頭、打開(kāi)系統(tǒng)攝像頭等;
?CameraDevice : 用于描述系統(tǒng)攝像頭,可用于關(guān)閉相機(jī)、創(chuàng)建相機(jī)會(huì)話、發(fā)送拍照請(qǐng)求等;
?CameraCharacteristics :用于描述攝像頭所支持的各種特性;
?CameraCaptureSession :當(dāng)程序需要預(yù)覽、拍照時(shí),都需要先通過(guò) CameraCaptureSession 來(lái)實(shí)現(xiàn)。該會(huì)話通過(guò)調(diào)用方法 setRepeatingRequest() 實(shí)現(xiàn)預(yù)覽;
?CameraRequest :代表一次捕獲請(qǐng)求,用于描述捕獲圖片的各種參數(shù)設(shè)置;
?CameraRequest.Builder :負(fù)責(zé)生成 CameraRequest 對(duì)象。

2. 相機(jī)預(yù)覽

下面通過(guò)源碼來(lái)講解如何使用 Camera2 來(lái)實(shí)現(xiàn)相機(jī)的預(yù)覽功能。

2.1 相機(jī)權(quán)限設(shè)置

Android Camera2 預(yù)覽功能實(shí)現(xiàn)

2.2 App 布局

?activity_main.xml

?fragment_camera.xml
?

2.3 相機(jī)自定義View

public?class?AutoFitTextureView?extends?TextureView?{?private?int?mRatioWidth?=?0;?private?int?mRatioHeight?=?0;?public?AutoFitTextureView(Context?context)?{?this(context,?null);
?}?public?AutoFitTextureView(Context?context,?AttributeSet?attrs)?{?this(context,?attrs,?0);
?}?public?AutoFitTextureView(Context?context,?AttributeSet?attrs,?int?defStyle)?{?super(context,?attrs,?defStyle);
?}?public?void?setAspectRatio(int?width,?int?height)?{?if?(width?

Android Camera2 預(yù)覽功能實(shí)現(xiàn)

2.4 動(dòng)態(tài)申請(qǐng)相機(jī)權(quán)限

public?class?MainActivity?extends?AppCompatActivity?{?private?static?final?int?REQUEST_PERMISSION?=?1;?@Override
?protected?void?onCreate(Bundle?savedInstanceState)?{?super.onCreate(savedInstanceState);
?setContentView(R.layout.activity_main);?if?(hasPermission())?{?if?(null?==?savedInstanceState)?{
?setFragment();
?}
?}?else?{
?requestPermission();
?}
?}?@Override
?public?void?onRequestPermissionsResult(int?requestCode,?String?permissions[],?int[]?grantResults)?{?if?(requestCode?==?REQUEST_PERMISSION)?{?if?(grantResults.length?==?1?&&?grantResults[0]?==?PackageManager.PERMISSION_GRANTED)?{
?setFragment();
?}?else?{
?requestPermission();
?}
?}?else?{?super.onRequestPermissionsResult(requestCode,?permissions,?grantResults);
?}
?}?//?權(quán)限判斷,當(dāng)系統(tǒng)版本大于23時(shí),才有必要判斷是否獲取權(quán)限
?private?boolean?hasPermission()?{?if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.M)?{?return?checkSelfPermission(Manifest.permission.CAMERA)?==?PackageManager.PERMISSION_GRANTED;
?}?else?{?return?true;
?}
?}?//?請(qǐng)求相機(jī)權(quán)限
?private?void?requestPermission()?{?if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.M)?{?if?(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA))?{
?Toast.makeText(MainActivity.this,?"Camera?permission?are?required?for?this?demo",?Toast.LENGTH_LONG).show();
?}
?requestPermissions(new?String[]{Manifest.permission.CAMERA},?REQUEST_PERMISSION);
?}
?}?//?啟動(dòng)相機(jī)Fragment
?private?void?setFragment()?{
?getSupportFragmentManager()
?.beginTransaction()
?.replace(R.id.container,?CameraFragment.newInstance())
?.commitNowAllowingStateLoss();
?}
}

Android Camera2 預(yù)覽功能實(shí)現(xiàn)

2.5 開(kāi)啟相機(jī)預(yù)覽

首先,在onResume()中,我們需要開(kāi)啟一個(gè) HandlerThread,然后利用該線程的 Looper 對(duì)象構(gòu)建一個(gè) Handler 用于相機(jī)回調(diào)。

@Overridepublic?void?onResume()?{?super.onResume();
?startBackgroundThread();?//?When?the?screen?is?turned?off?and?turned?back?on,?the?SurfaceTexture?is?
?//?already?available,?and?"onSurfaceTextureAvailable"?will?not?be?called.?In?
?//?that?case,?we?can?open?a?camera?and?start?preview?from?here?(otherwise,?we?
?//?wait?until?the?surface?is?ready?in?the?SurfaceTextureListener).
?if?(mTextureView.isAvailable())?{
?openCamera(mTextureView.getWidth(),?mTextureView.getHeight());
?}?else?{
?mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
?}
}private?void?startBackgroundThread()?{
?mBackgroundThread?=?new?HandlerThread("CameraBackground");
?mBackgroundThread.start();
?mBackgroundHandler?=?new?Handler(mBackgroundThread.getLooper());
}
同時(shí),在?onPause()?中有對(duì)應(yīng)的?HandlerThread?關(guān)閉方法。

當(dāng)屏幕關(guān)閉后重新開(kāi)啟,SurfaceTexture?已經(jīng)就緒,此時(shí)不會(huì)觸發(fā)?onSurfaceTextureAvailable?回調(diào)。因此,我們判斷?mTextureView?如果可用,則直接打開(kāi)相機(jī),否則等待?SurfaceTexture?回調(diào)就緒后再開(kāi)啟相機(jī)。private?void?openCamera(int?width,?int?height)?{?if?(ContextCompat.checkSelfPermission(getActivity(),?Manifest.permission.CAMERA)
?!=?PackageManager.PERMISSION_GRANTED)?{?return;
?}
?setUpCameraOutputs(width,?height);
?configureTransform(width,?height);
?Activity?activity?=?getActivity();
?CameraManager?manager?=?(CameraManager)?activity.getSystemService(Context.CAMERA_SERVICE);?try?{?if?(!mCameraOpenCloseLock.tryAcquire(2500,?TimeUnit.MILLISECONDS))?{?throw?new?RuntimeException("Time?out?waiting?to?lock?camera?opening.");
?}
?manager.openCamera(mCameraId,?mStateCallback,?mBackgroundHandler);
?}?catch?(CameraAccessException?e)?{
?e.printStackTrace();
?}?catch?(InterruptedException?e)?{?throw?new?RuntimeException("Interrupted?while?trying?to?lock?camera?opening.",?e);
?}
}
開(kāi)啟相機(jī)時(shí),我們首先判斷是否具備相機(jī)權(quán)限,然后調(diào)用?setUpCameraOutputs?函數(shù)對(duì)相機(jī)參數(shù)進(jìn)行設(shè)置(包括指定攝像頭、相機(jī)預(yù)覽方向以及預(yù)覽尺寸的設(shè)定等),接下來(lái)調(diào)用?configureTransform?函數(shù)對(duì)預(yù)覽圖片的大小和方向進(jìn)行調(diào)整,最后獲取?CameraManager?對(duì)象開(kāi)啟相機(jī)。因?yàn)橄鄼C(jī)有可能會(huì)被其他進(jìn)程同時(shí)訪問(wèn),所以在開(kāi)啟相機(jī)時(shí)需要加鎖。private?final?CameraDevice.StateCallback?mStateCallback?=?new?CameraDevice.StateCallback()?{?@Override
?public?void?onOpened(@NonNull?CameraDevice?cameraDevice)?{
?mCameraOpenCloseLock.release();
?mCameraDevice?=?cameraDevice;
?createCameraPreviewSession();
?}?@Override
?public?void?onDisconnected(@NonNull?CameraDevice?cameraDevice)?{
?mCameraOpenCloseLock.release();
?cameraDevice.close();
?mCameraDevice?=?null;
?}?@Override
?public?void?onError(@NonNull?CameraDevice?cameraDevice,?int?error)?{
?mCameraOpenCloseLock.release();
?cameraDevice.close();
?mCameraDevice?=?null;
?Activity?activity?=?getActivity();?if?(null?!=?activity)?{
?activity.finish();
?}
?}
};

Android Camera2 預(yù)覽功能實(shí)現(xiàn)

相機(jī)開(kāi)啟時(shí)還會(huì)指定相機(jī)的狀態(tài)變化回調(diào)函數(shù) mStateCallback,如果相機(jī)成功開(kāi)啟,則開(kāi)始創(chuàng)建相機(jī)預(yù)覽會(huì)話。

private?void?createCameraPreviewSession()?{?try?{?//?獲取?texture?實(shí)例
?SurfaceTexture?texture?=?mTextureView.getSurfaceTexture();?assert?texture?!=?null;?//?設(shè)置?TextureView?緩沖區(qū)大小
?texture.setDefaultBufferSize(mPreviewSize.getWidth(),?mPreviewSize.getHeight());?//?獲取?Surface?顯示預(yù)覽數(shù)據(jù)
?Surface?surface?=?new?Surface(texture);?//?構(gòu)建適合相機(jī)預(yù)覽的請(qǐng)求
?mPreviewRequestBuilder?=?mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);?//?設(shè)置?surface?作為預(yù)覽數(shù)據(jù)的顯示界面
?mPreviewRequestBuilder.addTarget(surface);?//?創(chuàng)建相機(jī)捕獲會(huì)話用于預(yù)覽
?mCameraDevice.createCaptureSession(Arrays.asList(surface),?new?CameraCaptureSession.StateCallback()?{??@Override
??public?void?onConfigured(@NonNull?CameraCaptureSession?cameraCaptureSession)?{??//?如果相機(jī)關(guān)閉則返回
??if?(null?==?mCameraDevice)?{??return;
??}??//?如果會(huì)話準(zhǔn)備好則開(kāi)啟預(yù)覽
??mCaptureSession?=?cameraCaptureSession;??try?{??//?自動(dòng)對(duì)焦
??mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
???CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
??mPreviewRequest?=?mPreviewRequestBuilder.build();??//?設(shè)置反復(fù)捕獲數(shù)據(jù)的請(qǐng)求,預(yù)覽界面一直顯示畫(huà)面
??mCaptureSession.setRepeatingRequest(mPreviewRequest,???null,?mBackgroundHandler);
??}?catch?(CameraAccessException?e)?{
??e.printStackTrace();
??}
??}??@Override
??public?void?onConfigureFailed(
??@NonNull?CameraCaptureSession?cameraCaptureSession)?{
??showToast("Failed");
??}
?},?null
?);
?}?catch?(CameraAccessException?e)?{
?e.printStackTrace();
?}
}

Android Camera2 預(yù)覽功能實(shí)現(xiàn)

以上便是 Camera2 API 實(shí)現(xiàn)相機(jī)預(yù)覽的主要過(guò)程。有什么問(wèn)題歡迎一起交流討論


新聞標(biāo)題:AndroidCamera2預(yù)覽功能實(shí)現(xiàn)
當(dāng)前鏈接:http://weahome.cn/article/ppejsi.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部