天天看點

Android | 教你如何使用HwCameraKit接入相機人像模式

Android | 教你如何使用HwCameraKit接入相機人像模式

目錄

介紹

簡介

關于本次CodeLab

你将建立什麼

你會學到什麼

你需要什麼

申請Camera相關權限

內建HwCameraKit開放能力

步驟1 模式建立:擷取CameraKit執行個體,建立人像模式

步驟2 配置模式:配置模式的狀态回調,資料回調及處理這些回調的Handler,以及預覽、拍照分辨率等參數

步驟3 模式操作

3.1 開啟預覽

3.2 參數設定

步驟4 操作Callback

步驟5 模式釋放

恭喜你

HwCameraKit為開發者提供了一套相容EMUI的相機能力開放接口,開發者可以通過HwCameraKit使自己的應用快速接入華為相機的私有能力,擴充應用的拍攝功能,為使用者提供更好拍攝體驗。

人像模式為HwCameraKit開放的多種相機模式其中之一,它将允許您:

擷取華為相機的人像拍攝能力,包括背景虛化、環境光、瘦臉,皮膚光滑、調色等能力;

提供相機模式進階程式設計接口,簡化相機應用開發,并借助IDE工具快速接入上述能力。

在本次CodeLab中,您将使用HwCameraKit建立一款Android相機應用程式,使其可以獲得華為相機的人像拍攝功能,實作人像的虛化、美膚等效果。

普通拍攝(左) VS 人像模式開啟虛化(右)

使用HwCameraKit IDE高效內建華為相機開放能力

熟悉HwCameraKit基本開發模式

硬體要求

開發計算機(桌上型電腦或筆記本電腦)

作業系統為EMUI10.0及以上版本的華為手機

軟體要求

JAVA JDK安裝包

Android SDK包

HwCameraKit IDE工具:DevEco

Duration: 0:05

  1. 在工程的Manifest檔案中添加相關權限:
  1. 動态申請相關權限:

private static final String [] PERMISSIONS_ARRAY = new String[] {

Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_FINE_LOCATION           

};

private static List permissionsList = new ArrayList<>(PERMISSIONS_ARRAY.length);

/**

  • 動态請求WRITE_EXTERNAL_STORAGE CAMERA RECORD_AUDIO權限

    *

  • @param activity 應用activity

*/

public static void requestPermission (final Activity activity) {

for (String permission : PERMISSIONS_ARRAY) {
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
    permissionsList.add(permission);
}           

}

ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String [permissionsList.size()]), REQUEST_CODE_ASK_PERMISSIONS);           

Duration: 0:60

通過IDE提供的功能卡片,可以快速擷取示例代碼并将其添加到工程中,以人像模式為例,找到人像能力卡片:可通過Tools->EMUI Kits->Kit Assistant->Camera->Portrait Mode 來找到該卡片。

提示:本次Codelabs提供了配套的app開發工程,請使用IDE工具導入,并根據如下步驟,實作提供的配套工程中帶有/ TODO /注釋的方法,進而快速內建人像模式。

private @Mode.Type int mCurrentModeType;

private CameraKit mCameraKit;

private ModeCharacteristics mModeCharacteristics;

private void createMode() {

mCameraKit = CameraKit.getInstance(getApplicationContext());

if (mCameraKit == null) {
    Log.e(TAG, "This device does not   support CameraKit!");
}

/** Query camera id list*/

String[] cameraLists = mCameraKit . getCameraIdList ();

if ((cameraLists != null) && (cameraLists.length > 0)) {
    
    Log.i(TAG, "Try to use camera   with id " + cameraLists[0]);
    
    /** Query supported modes of this   device*/

    int[] modes = mCameraKit . getSupportedModes (cameraLists[0]);
    
    if (!Arrays.stream(modes).anyMatch((i)   -> i == mCurrentModeType)) {
        Log.w(TAG, "Current mode is   not supported in this device!");
        return;
    }
    mCameraKit.createMode(cameraLists[0], mCurrentModeType, mModeStateCallback, mCameraKitHandler);
}
           

從mModeStateCallback的onCreated回調後,可從入參可獲得人像Mode執行個體

/* 在onCreated回調中擷取mode對象,然後以行為的狀态回調和資料回調及對應的線程為入參,初始化ModeConfig.Builder,配置預覽的surface和拍照的大小,通過configure指令将配置項設定到mMode中,進行模式的激活/

private void configMode() {

Log.i(TAG, "configMode begin");

/** Query supported preview size*/

List<Size> previewSizes =   mModeCharacteristics.getSupportedPreviewSizes(SurfaceTexture.class);

/** Query supported capture size*/

List<Size> captureSizes =   mModeCharacteristics.getSupportedCaptureSizes(ImageFormat.JPEG);

Log.d(TAG, "configMode: captureSizes   = " + captureSizes.size() + ";previewSizes=" +   previewSizes.size());

/** Use the first one or default   4000x3000*/
mCaptureSize =   captureSizes.stream().findFirst().orElse(new Size(4000, 3000));
/** Use the same ratio with preview*/

mPreviewSize =   previewSizes.stream().filter((size) -> Math.abs((1.0f * size.getHeight() /   size.getWidth()) - (1.0f * mCaptureSize.getHeight() /   mCaptureSize.getWidth())) < 0.01).findFirst().get();
Log.i(TAG, "configMode: mCaptureSize   = " + mCaptureSize + ";mPreviewSize=" + mPreviewSize);

/** Update view*/

runOnUiThread(() ->   mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth()));

SurfaceTexture texture =   mTextureView.getSurfaceTexture();

if (texture == null) {
    Log.e(TAG, "configMode:   texture=null!");
    return;
}

/** Set buffer size of view*/

texture.setDefaultBufferSize(mPreviewSize.getWidth(),   mPreviewSize.getHeight());

/** Get surface of texture*/

Surface surface = new Surface(texture);

/** Add preview and capture parameters to   config builder*/

modeConfigBuilder.addPreviewSurface(surface).addCaptureImage(mCaptureSize,   ImageFormat.JPEG);

/** Set callback for config builder*/

modeConfigBuilder.setDataCallback(actionDataCallback,   mCameraKitHandler);

modeConfigBuilder.setStateCallback(actionStateCallback,   mCameraKitHandler);

/** Configure mode*/

mMode.configure();
Log.i(TAG, "configMode end");           

使用構造器ModeConfig.Builder配置模式的狀态回調及資料回調及執行回調所在的Handler。從狀态回調中,開發者可以擷取如啟動預覽後狀态變化、拍照結束狀态、手動對焦結束、人臉檢測結果傳回等資訊;從資料回調中,開發者可擷取模式動作執行過程中産生資料結果(如拍照圖像資料等)。還可通過ModeConfig.Builder配置預覽Surface及拍照分辨率。

/ 在接收到到onConfigured回調後,說明mode配置成功,模式進入開啟狀态,此時調用startPreview指令開啟預覽。/

private void startPreview() {

mMode.startPreview();           

/ 使用者可以通過ModeCharacteristics#getSupportedParameters查詢目前模式下支援的參數(以人像模式為例:支援背景虛化,美膚等),通過ModeCharacteristics#getParameterRange查詢參數支援的取值範圍,通過Mode#setParameter設定對應效果。/

/ 設定人像虛化 /

mMode.setParameter(RequestKey.HW_PORTRAIT_SPOTS_BOKEH, validValue);

/ 設定美膚:皮膚光滑 /

int[] smoothLevels = modeCharacteristics.getSupportedBeauty(Metadata.BeautyType.HW_BEAUTY_SKIN_SMOOTH);

if (smoothLevels != null && smoothLevels.length != 0) {

mMode.setBeauty(Metadata.BeautyType.HW_BEAUTY_SKIN_SMOOTH,smoothLevels[smoothLevels.length - 1]);

/ 使用者可以通過設計按鈕等方式,調用takePicture進行拍照,異步通過onImageAvailable回調,傳回照片Image資料。/

mMode.takePicture();

/ 以資料回調為例,在拍照後從回調裡擷取圖檔 /

private final ActionDataCallback actionDataCallback = new ActionDataCallback() {

@Override
public void onImageAvailable(Mode mode,   int id, Image image) {
    super.onImageAvailable(mode, id,   image);
    Log.d(TAG,   "onImageAvailable");
    new ImageSaver(image, mFile,   CameraKitActivity.this).run();
}           

提示:除了從ActionDataCallback擷取拍照圖檔等資料以外,從ActionStateCallback中還可擷取模式動作執行過程中,執行狀态結果的回調處理,如啟動預覽後狀态變化、拍照結束狀态、手動對焦結束、人臉檢測結果傳回等。

/ 應用切背景,需要将模式釋放 /

@Override

protected void onPause() {

if (mBackgroundHandler != null) {
    mBackgroundHandler.post(new   Runnable() {
        @Override
        public void run() {
            if (mMode != null) {
                mMode.release();
                mMode = null;
            }
        }
    });
}
super.onPause();           

HwCameraKit IDE插件的安裝和使用

利用HwCameraKit将華為相機開放能力接入app

更多HwCameraKit相關資訊請關注我們的官網:

https://developer.huawei.com/consumer/cn/CameraKit

往期連結:Android | 教你如何快速內建機器學習能力

内容來源:

https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201234569803940158&fid=3467

原作者:艾羅門特

原文位址

https://www.cnblogs.com/developer-huawei/p/12807242.html