CameraX 又是一個 Google 推出的 JetPack 組件 ,是一個新鮮玩意兒,故給大家分享下我在項目中的使用過程心得。。 CameraX 是什麼? Google 開發者文檔 對 CameraX 的評價如下: CameraX是一個Jetpack支持庫,旨在幫助您簡化相機應用程式的開發工作。 ...
CameraX 又是一個 Google 推出的 JetPack 組件 ,是一個新鮮玩意兒,故給大家分享下我在項目中的使用過程心得。。
CameraX 是什麼?
Google 開發者文檔 對 CameraX 的評價如下:
CameraX是一個Jetpack支持庫,旨在幫助您簡化相機應用程式的開發工作。它提供一致且易於使用的API介面,適用於大多數Android設備,可以向後相容至Android 5.0(API等級21)。
雖然它利用的是camera2的功能,但使用的是更為簡單且基於用例的方法,該方法具有生命周期感知能力。它還解決了設備相容性問題,因此您無需在代碼庫中包含設備專有代碼。這些功能減少了將相機功能添加到應用時需要編寫的代碼量。
最後,通過CameraX,開發者只需兩行代碼即可利用與預安裝的相機應用相同的相機體驗和功能 CameraX擴展 是可選插件,通過該插件,您可以在支持的設備上向自己的應用中添加人像,HDR,夜間模式和美顏等效果。
本人的愚見:CameraX 是 Google 為瞭解決開發者們開發有關相機功能時遇到諸如適配等各種問題的一件稱手的兵器。。
CameraX 入門
CameraX 還在測試alpha階段,截至目前核心庫最新的版本是 1.0.0-alpha05
,估計Google未來會繼續修複現有的bug和推出穩定版(我也不知道啥時候?)。
CameraX 在項目中使用
CameraX 是 基於 Camera2 構建的,內部實現細節很多與Google之前推出的Camera2相同,所以說之前使用過Camera2 的旁友們對於 CameraX 可能會有一種親切感hhh。而對於沒有接觸過Camera2或者說沒有接觸過相機功能開發的小?伴們,相信我,CameraX 入門的確是很簡單,很簡單,很簡單。
有關下麵的代碼是用 Java 實現的,相信使用 Kotlin的小伙伴,也能一看就懂,網上的資料也大部分是Kotlin的?
CameraX 依賴
首先是要在 build.gradle(Module:app)
添加 以下的依賴,可以根據具體的需求添加?
// CameraX 核心庫
def camerax_version = "1.0.0-alpha05"
// CameraX view
def camerax_view_version = "1.0.0-alpha02"
// CameraX 擴展 library
def camerax_ext_version = "1.0.0-alpha02"
implementation "androidx.camera:camera-core:$camerax_version"
//如果你要使用Camera2的擴展功能
implementation "androidx.camera:camera-camera2:$camerax_version"
// 如果你要使用 CameraX View
implementation "androidx.camera:camera-view:$camerax_view_version"
// 如果你要使用 CameraX 的 擴展功能
implementation "androidx.camera:camera-extensions:$camerax_ext_version"
//申請許可權
implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5'
CameraX 獲取許可權
使用CameraX還是需要我們聲明和動態申請的,畢竟我們還是會使用相機這個東西。
1、在 AndroidManifest.xml
里 註冊相關的許可權,相信大家都懂的~
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.permission.camera"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
2、在你的項目中合適的地方,動態申請下相關的許可權
為了方便省事,我使用了 RxPermissons
這個庫進行動態申請許可權和許可權的管理
@SuppressLint("CheckResult")
public void initPermission() {
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.request(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE)
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
if (aBoolean) {
//申請許可權成功,操作
} else {
//申請許可權失敗,操作
}
}
});
}
頁面佈局
眾所周知,無論是拍照前還是拍攝視頻,我們都希望可以看到當前的預覽,從而控制拍攝的效果,那麼CameraX是通過啥東東來讓我們進行預覽操作的呢?答案是 它的 TextureView
,我們需要在進行預覽的頁面的佈局XML里放入一個 TextureView
。
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="@+id/containerCamera"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent"
/>
</RelativeLayout>
那麼預覽的輸出到時候就會在這個 TextureView
上展示出來。
重頭戲來了,怎麼讓相機打開看到圖像並且可以保存拍攝的照片呢
1、 CameraX 的配置 (告訴 CameraX ,你想要做什麼)
CameraX 可以做的事情,總體來說分三個部分–圖像預覽PreView,圖像分析Analyze,圖像拍攝Capture。
我們要分別對它們進行配置,告訴 CameraX 我們要怎麼用它們。
ImageCapture類、ImageAnalysis類、Preview類的對象就是我們具體操作使用的對象
配置過程如下:
ImageCapture imageCapture;
ImageAnalysis imageAnalysis;
Preview preview;
void initCameraConfig() {
//拍攝預覽的配置config
PreviewConfig.Builder configBuilder = new PreviewConfig.Builder().setLensFacing(CameraX.LensFacing.BACK);
preview = new Preview(configBuilder.build());
//圖片分析的配置config,Size對象裡面解析度,CameraX會自動找最適合當前設備的解析度
ImageAnalysisConfig imageAnalysisConfig = new ImageAnalysisConfig.Builder().setTargetResolution(new Size(1080,2248)).build();
imageAnalysis = new ImageAnalysis(imageAnalysisConfig);
//圖片拍攝的配置config
ImageCaptureConfig.Builder captureBuilder = new ImageCaptureConfig.Builder().setLensFacing(CameraX.LensFacing.BACK);
imageCapture = new ImageCapture(captureBuilder.build());
}
2、如何使用ImageCapture類、ImageAnalysis類、Preview類的對象呢?
首先要把它們加入到 LifeCycle上管理
CameraX.bindToLifecycle(getSelf(), preview, imageAnalysis, imageCapture);
然後為它們註冊綁定相關的事件
首先是 圖像預覽 和 圖像分析 的事件
//圖像預覽的具體操作
preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
@Override
public void onUpdated(Preview.PreviewOutput output) {
//下麵這一步很重要
//把預覽的輸出附加在自己的TextureView控制項上,這樣才可以看見預覽
containerCamera.setSurfaceTexture(output.getSurfaceTexture());
}
});
//圖像分析的具體操作
imageAnalysis.setAnalyzer(new ImageAnalysis.Analyzer() {
@Override
public void analyze(ImageProxy image, int rotationDegrees) {
// image 會不斷傳進來,你可以對它進行各種你想要的操作
}
});
拍攝、保存照片的操作比上面的多了一丟丟,不過也是灰常簡單的!
//創建要存儲照片的File,要記得檢查許可權的獲取
String imageName = "QG7777777.png";
//下麵是拍攝照片的輸出與回調,可以綁定一個按鈕的點擊事件之類的
imageCapture.takePicture(createImageFile(imageName), new ImageCapture.OnImageSavedListener() {
@SuppressLint("CheckResult")
@Override
public void onImageSaved(@NonNull File file) {
//成功保存照片後的回調
}
@Override
public void onError(@NonNull ImageCapture.ImageCaptureError imageCaptureError, @NonNull String message, @Nullable Throwable cause) {
//保存照片失敗後的回調
String errorMsg = "發生了未知的錯誤";
if(cause != null) {
errorMsg = cause.getMessage();
}
}
});
//保存指定名稱的文件,絕對路徑為"/storage/emulated/0/"+imageName
File createImageFile(String imageName) {
return new File(Environment.getExternalStorageDirectory(),imageName);
}
好啦,按步驟做到這裡,你已經可以拍攝出一張由CameraX 拍攝的照片了。
還不夠,想要更多的基礎操作?
CameraX 也支持很多的基礎操作,下麵以 1.0.0-alpha05
已經支持的 點擊對焦 操作為例
CameraX 將對焦操作,(我認為的) 濃縮成了三步:
1、獲取用戶點擊畫面區域的屏幕坐標
2、將屏幕坐標系的坐標轉換為CameraX能讀懂的坐標
3、告訴CameraX ,你想要開啟點擊對焦操作(配置)
對焦操作很簡單,獲取點擊畫面區域的坐標方法很多很多,我的代碼,參考如下:
/**
*點擊畫面區域進行對焦操作的實現
*/
containerCamera.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
TextureViewMeteringPointFactory pointFactory = new TextureViewMeteringPointFactory(containerCamera);
MeteringPoint meteringPoint = pointFactory.createPoint(event.getX(),event.getY());
FocusMeteringAction action = FocusMeteringAction.Builder
.from(meteringPoint)
.build();
try { CameraX.getCameraControl(CameraX.LensFacing.BACK).startFocusAndMetering(action);
} catch (CameraInfoUnavailableException e) {
e.printStackTrace();
}
return false;
}
});
擴展功能,Extensions ?
沒錯,CameraX 還支持 很多 擴展的功能,諸如開啟 HDR ,開啟 人像 模式,開啟 **美顏模式 **等等等。。
CameraX 將擴展功能的開啟 也 大大濃縮了,而且會自動判斷設備是否支持開啟。o( ̄▽ ̄)d
下麵以開啟 HDR 為例,讓我們回到 配置 config 那一塊
首先檢查自己的 build.gradle(Module:app)
有沒有 CameraX extensions 插件的依賴,沒有的先補上。
在創建preview 和 imageCapture 對象的時候就把 我們想要 開啟HDR 操作 告訴 CameraX,它就會幫我們檢測設備是否支持並開啟HDR這個功能了。
就是這麼地簡單,沒有了以前的繁瑣操作和適配問題。。
//拍攝預覽的配置config
PreviewConfig.Builder configBuilder = new PreviewConfig.Builder().setLensFacing(CameraX.LensFacing.BACK);
HdrPreviewExtender hdrPreviewExtender = HdrPreviewExtender.create(configBuilder);
//拍攝預覽,開啟HDR,判斷硬體條件是否支持開啟,是則直接開啟
if(hdrPreviewExtender.isExtensionAvailable()) {
hdrPreviewExtender.enableExtension();
}
preview = new Preview(configBuilder.build());
//圖片拍攝的配置config
ImageCaptureConfig.Builder captureBuilder = new ImageCaptureConfig.Builder().setLensFacing(CameraX.LensFacing.BACK);
HdrImageCaptureExtender hdrImageCaptureExtender = HdrImageCaptureExtender.create(captureBuilder);
//拍攝照片,開啟HDR,判斷硬體條件是否支持開啟,是則直接開啟
if(hdrImageCaptureExtender.isExtensionAvailable()) {
hdrImageCaptureExtender.isExtensionAvailable();
}
imageCapture = new ImageCapture(captureBuilder.build());
總結
CameraX 是 Google 推出的一個挺不錯的 JetPack 組件,入門真的非常簡單,使用起來很方便,節省了很多開發時間。而且綁定了LifeCycle ,因此生命周期管理也挺省事。
雖說目前還不太成熟,但畢竟它還在測試階段,Google未來還會修複bug和推出新功能,期待它的未來~
這篇文章只是介紹了CameraX的入門操作,想要瞭解更多和獲取最新的信息,請前往Google家的文檔。