Android JetPack組件-CameraX初探

来源:https://www.cnblogs.com/DMingO/archive/2020/05/05/12790056.html
-Advertisement-
Play Games

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家的文檔。

Google的開發者文檔:CameraX


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • mysql命令gruop by報錯this is incompatible with sql_mode=only_full_group_by 出現這個錯誤已導致在開發中mybatis的sql也運行不了 原因: 看一下group by的語法: select 選取分組中的列+聚合函數 from 表名稱 ...
  • 目錄:andorid jar/庫源碼解析 RxJava2: 作用: 通過提供一種,觀察者和訂閱者的模式,的架構,來優化邏輯流程。適用於複雜和需要多數據轉換和長流程。 慄子: 定義三個對象類 public class ResultInfo { public int code; public Strin ...
  • 目錄:andorid jar/庫源碼解析 Bolts: 作用: 用於鏈式執行跨線程代碼,且傳遞數據 慄子: Task.call(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return tr ...
  • 快速接入訊飛語音聽寫SDK(內附空指針解決和修改對話框文字方法) ...
  • 簡單又詳細,Android Library 發佈開源庫 JCenter & JitPack 攻略~ ...
  • 前言 最近項目有一個節點進度條的小需求,完成後,想分享出來希望可以幫到有需要的同學。 真機效果圖 自定義View完整代碼 開箱即用~,註釋已經炒雞詳細了 註意點 1. 控制項的節點總個數是與傳入的節點底部標題列表中元素個數控制(相同)的,簡而言之就是傳入的標題列表中有多少個標題,節點就會繪製多少個 2 ...
  • 一、ValueAnimator ValueAnimator是值的變動,可以控制控制項的一些值,從而達到變化動畫的效果。 監聽器三個 移除監聽器 當移除監聽器時,正在執行的動畫不會受到影響,但是之後再執行動畫,動畫的監聽效果將不會再呈現。 不常用函數 常用函數 效果: 二、自定義插值器 1.插值器的理解 ...
  • 前言 Excel 解析,一般來說是在服務端進行的,但是如果移動端要實現解析Excel的功能,那也是有實現的方法的。 不過由於Android 原生用Java/Kotlin實現,所以也可以參考服務端解析Excel的方法。 首先說, jxl ,過去比較流行的解析office文檔的框架,但目前官方的版本,在 ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...