GPUImage美白效果
原理部分來自網絡前輩的文檔, 各位可以參考 袁崢的微博
美顏原理
采集視頻 => 獲取每一幀圖片 => 濾鏡處理 => GPUImageView展示
美顏基本概念
GPU:(Graphic Processor Unit圖形處理單元)手機或者電腦用于圖像處理和渲染的硬件
GPU工作原理:采集數據-> 存入主內存(RAM) -> CPU(計算處理) -> 存入顯存(VRAM) -> GPU(完成圖像渲染) -> 幀緩沖區 -> 顯示器
OpenGL ES:(Open Graphics Library For Embedded(嵌入的) Systems 開源嵌入式系統圖形處理框架),一套圖形與硬件接口,用于把處理好的圖片顯示到屏幕上。
GPUImage:是一個基于OpenGL ES 2.0圖像和視頻處理的開源iOS框架,提供各種各樣的圖像處理濾鏡,并且支持照相機和攝像機的實時濾鏡,內置120多種濾鏡效果,并且能夠自定義圖像濾鏡。
濾鏡處理的原理:就是把靜態圖片或者視頻的每一幀進行圖形變換再顯示出來。它的本質就是像素點的坐標和顏色變化
GPUImage處理畫面原理
GPUImage采用鏈式方式來處理畫面,通過addTarget:方法為鏈條添加每個環節的對象,處理完一個target,就會把上一個環節處理好的圖像數據傳遞下一個target去處理,稱為GPUImage處理鏈
例如:
// 4, 給輸入資源對象添加過濾器
[self.imagePicture addTarget:self.filter1];
// 5, 過濾器關聯GPUImageview,用于展示
[self.filter1 addTarget:self.gpuImageView];
一般的target可分為兩類:
- 中間環節的target, 一般是各種filter, 是GPUImageFilter或者是子類.
- 最終環節的target, GPUImageView:用于顯示到屏幕上, 或者GPUImageMovieWriter:寫成視頻文件
GPUImage處理主要分為3個環節
- source(視頻、圖片源) -> filter(濾鏡) -> final target (處理后視頻、圖片)
GPUImaged的Source:都繼承GPUImageOutput的子類,作為GPUImage的數據源
- GPUImageVideoCamera:用于實時拍攝視頻
- GPUImageStillCamera:用于實時拍攝照片
- GPUImagePicture:用于處理已經拍攝好的圖片,比如png,jpg圖片
- GPUImageMovie:用于處理已經拍攝好的視頻,比如mp4文件
GPUImage的filter:GPUimageFilter類或者子類,這個類繼承自GPUImageOutput,并且遵守GPUImageInput協議,這樣既能流進,又能流出,就好比我們的墨鏡,光線通過墨鏡的處理,最終進入我們眼睛
GPUImage的final target:GPUImageView,GPUImageMovieWriter就好比我們眼睛,最終輸入目標
GPUImage處理原理
美顏用到的兩個類
- 磨皮(GPUImageBilateralFilter):本質就是讓像素點模糊,可以使用高斯模糊,但是可能導致邊緣會不清晰,用雙邊濾波(Bilateral Filter) ,有針對性的模糊像素點,能保證邊緣不被模糊。
- 美白(GPUImageBrightnessFilter):本質就是提高亮度
綜合實例
用到的屬性
@property(nonatomic,strong) GPUImageVideoCamera *videoCamera; // 相機
@property(nonatomic,strong) GPUImageBilateralFilter *bilateralFilter; // 雙邊模糊
@property(nonatomic,strong) GPUImageBrightnessFilter *brightnessFilter; // 亮度
@property (nonatomic, weak) GPUImageView *captureVideoPreview;
3種方式實現圖片的美白效果
#pragma mark 不加濾鏡組合
-(void)test1
{
//1, 創建源文件-- 直接匹配最高的分辨率
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait; // 方向
self.videoCamera = videoCamera;
//2, 創建濾鏡
// 磨皮濾鏡-- 雙邊模糊-- GPUImageBilateralFilter
GPUImageBilateralFilter *bilateralFilter = [[GPUImageBilateralFilter alloc]init];
bilateralFilter.distanceNormalizationFactor = 8; // 模糊度數值越大越不模糊,默認值是8大于1
// 美白濾鏡-- 亮度 亮度:調整亮度(-1.0 - 1.0,默認為0.0)
GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
brightnessFilter.brightness = 0.0;
//3, 創建輸出(1, 顯示,2推流)
GPUImageView *gpuiamgeView = [[GPUImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.view addSubview:gpuiamgeView];
//4 設置處理鏈
[videoCamera addTarget:bilateralFilter];
[bilateralFilter addTarget:brightnessFilter];
[brightnessFilter addTarget:gpuiamgeView];
// 5 開始獲取錄制
[self.videoCamera startCameraCapture];
}
濾鏡組合
#pragma mark 濾鏡組合
-(void)test2
{
// 創建視頻源
// SessionPreset:屏幕分辨率,AVCaptureSessionPresetHigh會自適應高分辨率
// cameraPosition:攝像頭方向
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
_videoCamera = videoCamera;
// 創建最終預覽View
GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:captureVideoPreview atIndex:0];
// 創建濾鏡:磨皮,美白,組合濾鏡
GPUImageFilterGroup *groupFilter = [[GPUImageFilterGroup alloc] init];
// 磨皮濾鏡
GPUImageBilateralFilter *bilateralFilter = [[GPUImageBilateralFilter alloc] init];
[groupFilter addTarget:bilateralFilter];
_bilateralFilter = bilateralFilter;
// 美白濾鏡
GPUImageBrightnessFilter *brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
[groupFilter addTarget:brightnessFilter];
_brightnessFilter = brightnessFilter;
// 設置濾鏡組鏈
[bilateralFilter addTarget:brightnessFilter];
[groupFilter setInitialFilters:@[bilateralFilter]];
groupFilter.terminalFilter = brightnessFilter;
// 設置GPUImage響應鏈,從數據源 => 濾鏡 => 最終界面效果
[videoCamera addTarget:groupFilter];
[groupFilter addTarget:captureVideoPreview];
// 必須調用startCameraCapture,底層才會把采集到的視頻源,渲染到GPUImageView中,就能顯示了。
// 開始采集視頻
[videoCamera startCameraCapture];
}
以上兩個方法中改變美顏的參數
- (IBAction)bilateralFilter:(UISlider *)sender
{
// 值越小,磨皮效果越好
CGFloat maxValue = 10;
[_bilateralFilter setDistanceNormalizationFactor:(maxValue - sender.value)];
}
- (IBAction)brightnessFilter:(UISlider *)sender
{
_brightnessFilter.brightness = sender.value;
}
第三方
#import "GPUImageBeautifyFilter.h"
-(void)test3
{
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
_videoCamera = videoCamera;
// 創建最終預覽View
GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:captureVideoPreview atIndex:0];
_captureVideoPreview = captureVideoPreview;
// 設置處理鏈
[_videoCamera addTarget:_captureVideoPreview];
// 必須調用startCameraCapture,底層才會把采集到的視頻源,渲染到GPUImageView中,就能顯示了。
// 開始采集視頻
[videoCamera startCameraCapture];
}
- (IBAction)beautifulSDK:(UISwitch *)sender
{
// 切換美顏效果原理:移除之前所有處理鏈,重新設置處理鏈
if (sender.on)
{
// 移除之前所有處理鏈
[_videoCamera removeAllTargets];
// 創建美顏濾鏡
GPUImageBeautifyFilter *beautifyFilter = [[GPUImageBeautifyFilter alloc] init];
// 設置GPUImage處理鏈,從數據源 => 濾鏡 => 最終界面效果
[_videoCamera addTarget:beautifyFilter];
[beautifyFilter addTarget:_captureVideoPreview];
}
else
{
// 移除之前所有處理鏈
[_videoCamera removeAllTargets];
[_videoCamera addTarget:_captureVideoPreview];
}
}