記錄--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 失敗,請參考
元件功能
- 人臉標記,返回人臉個數
- 濾鏡美顏(基於GPUImage),美顏程度可調節(0~9)
- 相機功能,包括拍照、轉換前後鏡頭,其餘相機功能可自行擴充套件
效果如下圖
如何使用
程式碼檔案
- 新增 demo 的 ios 資料夾下的 Camera 到自己專案的 ios 目錄下,
- ios中新增相關相機相簿許可權配置
<key>NSCameraUsageDescription</key> <string>上傳頭像時,使用您的相機來拍攝照片</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>儲存圖片時,使用您的相簿來儲存照片</string> <key>NSPhotoLibraryUsageDescription</key> <string>上傳頭像時,使用您的相簿來獲取圖片</string>
- 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 ,雙擊
介紹
程式碼中已經加了比較多的註釋,這裡主要根據檔案來說一些我覺得要關注的點。
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,閱讀程式碼