AndroidCamera2預覽功能實現(xiàn)-創(chuàng)新互聯(lián)

1. 概述

慈利網(wǎng)站建設公司成都創(chuàng)新互聯(lián),慈利網(wǎng)站設計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為慈利成百上千提供企業(yè)網(wǎng)站建設服務。企業(yè)網(wǎng)站搭建\外貿網(wǎng)站建設要多少錢,請找那個售后服務好的慈利做網(wǎng)站的公司定做!

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

全新的 Camera2 在 Camera 的基礎上進行了改造,大幅提升了 Android 系統(tǒng)的拍照功能。它通過以下幾個類與方法來實現(xiàn)相機預覽時的工作過程:

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

2. 相機預覽

下面通過源碼來講解如何使用 Camera2 來實現(xiàn)相機的預覽功能。

2.1 相機權限設置

<uses-permission?android:name="android.permission.CAMERA"?/>

Android Camera2 預覽功能實現(xiàn)

2.2 App 布局

?activity_main.xml

<?xml?version="1.0"?encoding="utf-8"?><FrameLayout?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"
?android:background="#000"
?tools:context=".MainActivity"></FrameLayout>?fragment_camera.xml<?xml?version="1.0"?encoding="utf-8"?><RelativeLayout?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"
?tools:context=".CameraFragment">
?<com.lightweh.camera2preview.AutoFitTextureView
?android:id="@+id/textureView"
?android:layout_width="wrap_content"
?android:layout_height="wrap_content"
?android:layout_centerVertical="true"
?android:layout_centerHorizontal="true"?/></RelativeLayout>

2.3 相機自定義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?<?0?||?height?<?0)?{?throw?new?IllegalArgumentException("Size?cannot?be?negative.");
?}
?mRatioWidth?=?width;
?mRatioHeight?=?height;
?requestLayout();
?}?@Override
?protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{?super.onMeasure(widthMeasureSpec,?heightMeasureSpec);?int?width?=?MeasureSpec.getSize(widthMeasureSpec);?int?height?=?MeasureSpec.getSize(heightMeasureSpec);?if?(0?==?mRatioWidth?||?0?==?mRatioHeight)?{
?setMeasuredDimension(width,?height);
?}?else?{?if?(width?<?height?*?mRatioWidth?/?mRatioHeight)?{
?setMeasuredDimension(width,?width?*?mRatioHeight?/?mRatioWidth);
?}?else?{
?setMeasuredDimension(height?*?mRatioWidth?/?mRatioHeight,?height);
?}
?}
?}
}

Android Camera2 預覽功能實現(xiàn)

2.4 動態(tài)申請相機權限

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);
?}
?}?//?權限判斷,當系統(tǒng)版本大于23時,才有必要判斷是否獲取權限
?private?boolean?hasPermission()?{?if?(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.M)?{?return?checkSelfPermission(Manifest.permission.CAMERA)?==?PackageManager.PERMISSION_GRANTED;
?}?else?{?return?true;
?}
?}?//?請求相機權限
?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);
?}
?}?//?啟動相機Fragment
?private?void?setFragment()?{
?getSupportFragmentManager()
?.beginTransaction()
?.replace(R.id.container,?CameraFragment.newInstance())
?.commitNowAllowingStateLoss();
?}
}

Android Camera2 預覽功能實現(xiàn)

2.5 開啟相機預覽

首先,在onResume()中,我們需要開啟一個 HandlerThread,然后利用該線程的 Looper 對象構建一個 Handler 用于相機回調。

@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());
}
同時,在?onPause()?中有對應的?HandlerThread?關閉方法。

當屏幕關閉后重新開啟,SurfaceTexture?已經(jīng)就緒,此時不會觸發(fā)?onSurfaceTextureAvailable?回調。因此,我們判斷?mTextureView?如果可用,則直接打開相機,否則等待?SurfaceTexture?回調就緒后再開啟相機。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);
?}
}
開啟相機時,我們首先判斷是否具備相機權限,然后調用?setUpCameraOutputs?函數(shù)對相機參數(shù)進行設置(包括指定攝像頭、相機預覽方向以及預覽尺寸的設定等),接下來調用?configureTransform?函數(shù)對預覽圖片的大小和方向進行調整,最后獲取?CameraManager?對象開啟相機。因為相機有可能會被其他進程同時訪問,所以在開啟相機時需要加鎖。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 預覽功能實現(xiàn)

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

private?void?createCameraPreviewSession()?{?try?{?//?獲取?texture?實例
?SurfaceTexture?texture?=?mTextureView.getSurfaceTexture();?assert?texture?!=?null;?//?設置?TextureView?緩沖區(qū)大小
?texture.setDefaultBufferSize(mPreviewSize.getWidth(),?mPreviewSize.getHeight());?//?獲取?Surface?顯示預覽數(shù)據(jù)
?Surface?surface?=?new?Surface(texture);?//?構建適合相機預覽的請求
?mPreviewRequestBuilder?=?mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);?//?設置?surface?作為預覽數(shù)據(jù)的顯示界面
?mPreviewRequestBuilder.addTarget(surface);?//?創(chuàng)建相機捕獲會話用于預覽
?mCameraDevice.createCaptureSession(Arrays.asList(surface),?new?CameraCaptureSession.StateCallback()?{??@Override
??public?void?onConfigured(@NonNull?CameraCaptureSession?cameraCaptureSession)?{??//?如果相機關閉則返回
??if?(null?==?mCameraDevice)?{??return;
??}??//?如果會話準備好則開啟預覽
??mCaptureSession?=?cameraCaptureSession;??try?{??//?自動對焦
??mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
???CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
??mPreviewRequest?=?mPreviewRequestBuilder.build();??//?設置反復捕獲數(shù)據(jù)的請求,預覽界面一直顯示畫面
??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 預覽功能實現(xiàn)

以上便是 Camera2 API 實現(xiàn)相機預覽的主要過程。有什么問題歡迎一起交流討論

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

分享題目:AndroidCamera2預覽功能實現(xiàn)-創(chuàng)新互聯(lián)
本文鏈接:http://bm7419.com/article42/dssehc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供面包屑導航、外貿建站、微信公眾號、靜態(tài)網(wǎng)站ChatGPT、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設