1. 程式人生 > 其它 >記錄--react native 封裝人臉 檢測、美顏元件

記錄--react native 封裝人臉 檢測、美顏元件

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

本元件目前只能用在React Native 的iOS端

本元件來之實際中的開發需求:可以檢測並且標記人臉,實現基本的美顏,可進行拍照、換行鏡頭等基礎相機功能。官方元件封裝 教程

本文程式碼:DEMO 執行demo

$ git clone https://github.com/lianglei777/demos.git
$ cd demos
$ git checkout RNFaceDemo
$ cd RNFaceDemo
$ npm install 
$ cd ios 
$ pod install

如果 pod install 失敗,請參考

此文 的 cocoapods 部分。

元件功能

  • 人臉標記,返回人臉個數
  • 濾鏡美顏(基於GPUImage),美顏程度可調節(0~9)
  • 相機功能,包括拍照、轉換前後鏡頭,其餘相機功能可自行擴充套件

效果如下圖

如何使用

程式碼檔案

  1. 新增 demo 的 ios 資料夾下的 Camera 到自己專案的 ios 目錄下,
  2. ios中新增相關相機相簿許可權配置
  <key>NSCameraUsageDescription</key>
  <string>上傳頭像時,使用您的相機來拍攝照片</string>
  <key>NSPhotoLibraryAddUsageDescription</key>
  <string>儲存圖片時,使用您的相簿來儲存照片</string>
  <key>NSPhotoLibraryUsageDescription</key>
  <string>上傳頭像時,使用您的相簿來獲取圖片</string>
  1. js 層使用參考 NativeModule/RNFaceDetectView.js 和 Pages/ComponentBridgeDemo.js

安裝GPUImage

Podfile 檔案中新增如下內容, 執行 pod install

pod 'GPUImage',:git => 'https://github.com/lianglei777/GPUImage.git'

cmd + b 進行編譯,如果遇到以下問題

錯誤1

解決方法: 按照如下途中點選步驟,新增 libGPUImage.a 檔案

錯誤2

解決方法: Build Settings --》 Library Search Paths ,雙擊

新增 "${PODS_CONFIGURATION_BUILD_DIR}/GPUImage",選擇 non-recursive

介紹

程式碼中已經加了比較多的註釋,這裡主要根據檔案來說一些我覺得要關注的點。

GPUImage

GPUImage 是一款利用GPU新增濾鏡效果,美化影象的 Object-C 庫,但是可惜的是 swift 出現之後作者放棄維護了,需要修改一些程式碼才能執行在較新的iOS版本中,這裡是我修改之後的 GPUImage 庫,也是元件中在用的

FSKGPUImageBeautyFilter

FSKGPUImageBeautyFilter 是基於 GPUImage 的美顏濾鏡,可以通過三個維度調整美顏效果。

/** 美顏程度 */
@property (nonatomic, assign) CGFloat beautyLevel;
/** 美白程度 */
@property (nonatomic, assign) CGFloat brightLevel;
/** 色調強度 */
@property (nonatomic, assign) CGFloat toneLevel;

這裡需要注意 FSKGPUImageBeautyFilter.m 檔案中 initWithFragmentShaderFromString 的定義方式,傳入的著色器引數如果不懂相關內容請不要修改,也不要為了程式碼美觀去新增空格個或則換行, 這都是我踩過的大坑,目前的程式碼都是除錯實際驗證過的,請放心使用。

RCTFaceDetectView

這裡是封裝元件的主要程式碼

RCTFaceDetectView.h

// 在 js 元件中使用的回撥方法, 必須使用 RCTBubblingEventBlock 來定義
@property(nonatomic,copy)RCTBubblingEventBlock onFaceCallback;
//傳入的美顏引數
@property(nonatomic,copy)NSString *beautyLevel;

+ (instancetype)sharedInstance; // 單例
- (UIView *)initBeautifyFaceView;  // 初始化相機介面

//相機切換前後攝像頭
- (void)switchCameraFrontOrBack;
//拍照
-(void)takeFaceDetectCamera:(RCTResponseSenderBlock)successBlock;

//設定美顏係數
-(void)setBeautyLevel:(NSString *)level;

// 停止相機捕捉
-(void)stopCamera;

此處需要注意

  • onFaceCallback 是在 js 元件中使用的回撥方法,必須使用 RCTBubblingEventBlock 定義,beautyLevel 是 prop 傳參,使用正常型別就可以

  • switchCameraFrontOrBack、takeFaceDetectCamera、stopCamera 是元件的功能方法,之前由於需求的原因,沒有封裝為元件的傳參方法,可以自定義相關呼叫方法暴露到 js 中,目前 demo 中沒有新增,暴露方法參考 中原生方法的封裝。寫法如下:

#pragma mark - 人臉檢測相機:拍照回撥拍照圖片base64
RCT_REMAP_METHOD(takeFaceDetectCameraWithCallback,takeFaceDetectCamera:(RCTResponseSenderBlock)successBlock){
  
  dispatch_async(dispatch_get_main_queue(), ^{
    [[RCTFaceDetectView sharedInstance] takeFaceDetectCamera:successBlock];
  });
}

#pragma mark - 人臉檢測相機:前後攝像頭切換
RCT_REMAP_METHOD(switchCameraFrontOrBack,switchCameraFrontOrBack){
  dispatch_async(dispatch_get_main_queue(), ^{
    [[RCTFaceDetectView sharedInstance] switchCameraFrontOrBack];
  });
}

#pragma mark - 人臉檢測相機:美顏係數
RCT_REMAP_METHOD(setFilterLevel,setBeautyLevel:(float)level){
  dispatch_async(dispatch_get_main_queue(), ^{
    [[RCTFaceDetectView sharedInstance] setBeautyLevel: [NSString stringWithFormat:@"%f",level]];
  });
}

#pragma mark --停止視訊流--
RCT_EXPORT_METHOD(stopFaceDetectCamera) {
   [[RCTFaceDetectView sharedInstance] stopCamera];
   [[RCTFaceDetectView sharedInstance] unobserveGlobalNotifications];
}

RCTFaceDetectView.m

要點介紹

如何獲取到人臉相關的引數

需要實現ios的代理方法,如下

#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
  ...
}

metadataObjects 引數中即包含了面部個數以及面部在攝像頭中的座標位置。

如何繪製面部框

此處需要進行座標轉換,將面部在攝像頭中的座標轉為在螢幕中的座標,此處需要使用 transformedMetadataObjectForMetadataObject 方法,具體請檢視程式碼

如何進行美顏

在 GPUImage 中使用 FSKGPUImageBeautyFilter 濾鏡,常規寫法。

RCTFaceDetectViewManager

將 RCTFaceDetectView 封裝的原生元件,暴露到 js 層

更多內容,執行 demo,閱讀程式碼

https://juejin.cn/post/6978297307733164068

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。