任何一款直播軟體都必須進行美顏,不然哪來的那麼多美女,所以技術改變世界,不只是說說而已。美顏在採集的時候就得就行,讓主播實時看到直播的效果。 1.美顏原理 其實美顏的本質就是美白和磨皮,分別通過提高亮度和模糊像素點進行。我們一般用GPUImage這個開 ...
任何一款直播軟體都必須進行美顏,不然哪來的那麼多美女,所以技術改變世界,不只是說說而已。美顏在採集的時候就得就行,讓主播實時看到直播的效果。
1.美顏原理
其實美顏的本質就是美白和磨皮,分別通過提高亮度和模糊像素點進行。我們一般用GPUImage這個開源的圖像處理庫來實現。視頻的本質就是一張張連續的圖片,磨皮就是對於圖片上的像素點的取值與周邊的像素點取值相關聯。常見的有高斯模糊和雙邊濾波(Bilateral Filter)。
高斯模糊是最常見的一種模糊方式,像素點取值是由周邊像素點求加權平均所得,而權重繫數則是像素間的距離的高斯函數,大致關係是距離越小、權重繫數越大。高斯模糊會導致邊緣不清晰。
雙邊濾波是有針對點的模糊像素點,能保證邊緣不被模糊。
2.GPUImage介紹
GPUImage 是一個開源的基於GPU的圖片或視頻的處理框架,其本身內置了多達120多種常見的濾鏡效果。有了它,添加實時的濾鏡只需要簡單地添加幾行代碼,非常強大。想研究源碼的同學上,可以去GitHub上下載。
3.效果
&esmp;&esmp;請原諒這篇只有UI效果圖。用兩個Slider來控制磨皮和美白的效果,從上到下取值範圍分別為[-1,1] [0,100];
4.GPUImage使用方法
1.用CocoaPods集成到項目中。
pod 'GPUImage', '~> 0.1.7'
2.代碼演示
#import "FHUImageFilterViewController.h"
#import <GPUImage/GPUImage.h>
@interface FHUImageFilterViewController ()
// 視頻源
@property (nonatomic, strong)GPUImageVideoCamera *videoCamera;
// 磨皮濾鏡
@property (nonatomic, weak)GPUImageBilateralFilter *bilateralFilter;
// 美白濾鏡
@property (nonatomic, weak)GPUImageBrightnessFilter *brightnessFilter;
@end
@implementation FHUImageFilterViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 創建視屏源
/*
* sessionPreset : 屏幕解析度
* cameraPosition: 攝像頭位置
**/
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
// 設置輸出圖像方向
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
self.videoCamera = videoCamera;
// 創建最終預覽View
GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
captureVideoPreview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view insertSubview:captureVideoPreview atIndex:0];
// 創建濾鏡:磨皮,美白,組合濾鏡
GPUImageFilterGroup *groupFilter = [[GPUImageFilterGroup alloc] init];
// 磨皮濾鏡
GPUImageBilateralFilter *bilateraFilter = [[GPUImageBilateralFilter alloc] init];
[groupFilter addTarget:bilateraFilter];
_bilateralFilter = bilateraFilter;
// 美白濾鏡
GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
[groupFilter addTarget:brightnessFilter];
_brightnessFilter = brightnessFilter;
// 設置濾鏡組鏈
[bilateraFilter addTarget:brightnessFilter];
[groupFilter setInitialFilters:@[bilateraFilter]];
groupFilter.terminalFilter = brightnessFilter;
// 設置GPUImage的響應鏈, 從數據源 ==> 濾鏡 ==> 最終界面效果
[videoCamera addTarget:groupFilter];
[groupFilter addTarget:captureVideoPreview];
// 必須採用startCameraCapture, 底層才會把採集到的視頻源,渲染到GPUImageView中,就能顯示了。
[videoCamera startCameraCapture];
}
備註:手機解析度(sessionPreset)有13個值可選,但最好設置成AVCaptureSessionPresetHigh,手機會自動識別。如果設置的太高,手機不支持,會直接報錯。
- (IBAction)brightnessFiller:(id)sender {
UISlider *slider = (UISlider *)sender;
// 亮度(brightness)
_brightnessFilter.brightness = slider.value;
}
- (IBAction)bilateralFilter:(id)sender {
UISlider *slider = (UISlider *)sender;
CGFloat maxValue = 100;
//平滑因數(distanceNormalizationFactor)
_bilateralFilter.distanceNormalizationFactor = maxValue - slider.value;
NSLog(@"distanceNormalizationFactor=%f",_bilateralFilter.distanceNormalizationFactor);
}
備註:(1)亮度(brightness)取值範圍[-1,1],0為正常狀態,預設。
(2)平滑因數(distanceNormalizationFactor)值越小,磨皮效果越好,預設為8。我為了演示效果,把最大值設置成100,這樣幾乎就沒有磨皮效果了,平時最好10以內。最好大於0,不然就會變形。
5.自定義濾鏡
如果你感覺GPUImage自帶的濾鏡不夠用的話,也可以自定義濾鏡,使用方式和上面的差不多。我以一個別人寫的美顏濾鏡為例。
1.demo下載地址。把GPUImageBeautifyFilter文件夾導入你的工程中。
2.代碼演示
#import "FHBeautyViewController.h"
#import "GPUImageBeautifyFilter.h"
#import <GPUImage/GPUImage.h>
@interface FHBeautyViewController ()
//視頻源一定要強引用
@property(nonatomic,strong) GPUImageVideoCamera *videoCamera;
@end
@implementation FHBeautyViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 創建視頻源
_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
_videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
// 創建美顏濾鏡
GPUImageBeautifyFilter *beautifyFilter = [[GPUImageBeautifyFilter alloc] init];
// 創建最終預覽View
GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
captureVideoPreview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view insertSubview:captureVideoPreview atIndex:0];
// 設置GPUImage處理鏈,從數據源 => 濾鏡 => 最終界面效果
[_videoCamera addTarget:beautifyFilter];
[beautifyFilter addTarget:captureVideoPreview];
// 開始採集視屏
[_videoCamera startCameraCapture];
}
6.demo下載
demo下載地址。下載下來運行,發現報錯。
那是因為我沒有在工程里上傳ijkplayer視屏直播框架,我能上傳上去,但下載太慢了,什麼原因大家都懂得。我把ijkplayer視屏直播框架放到百度雲上了,沒有密碼,下載下來之後,放到LiveAppDemo-master文件夾里,重新打開就可以運行了。