這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 本組件目前只能用在React Native 的iOS端 本組件來之實際中的開發需求:可以檢測並且標記人臉,實現基本的美顏,可進行拍照、換行鏡頭等基礎相機功能。官方組件封裝 教程 本文代碼:DEMO 運行demo $ git clone h ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
本組件目前只能用在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)
- 相機功能,包括拍照、轉換前後鏡頭,其餘相機功能可自行擴展
效果如下圖
如何使用
代碼文件
- 添加 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 ,雙擊添加 "${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,閱讀代碼