GPUImage
- GPUImage:是一個(gè)基于OpenGL ES 2.0圖像和視頻處理的開源iOS框架簸呈,提供各種各樣的圖像處理濾鏡牵敷,并且支持照相機(jī)和攝像機(jī)的實(shí)時(shí)濾鏡虽界,內(nèi)置120多種濾鏡效果炫加,并且能夠自定義圖像濾鏡窟哺。
濾鏡處理的原理:就是把靜態(tài)圖片或者視頻的每一幀進(jìn)行圖形變換再顯示出來泻轰。它的本質(zhì)就是像素點(diǎn)的坐標(biāo)和顏色變化
GPUImage處理畫面原理
- GPUImage采用鏈?zhǔn)椒绞絹硖幚懋嬅?通過addTarget:方法為鏈條添加每個(gè)環(huán)節(jié)的對(duì)象,處理完一個(gè)target,就會(huì)把上一個(gè)環(huán)節(jié)處理好的圖像數(shù)據(jù)傳遞下一個(gè)target去處理且轨,稱為GPUImage處理鏈浮声。
- 一般的target可分為兩類
- 中間環(huán)節(jié)的target, 一般是各種filter, 是GPUImageFilter或者是子類.
- 最終環(huán)節(jié)的target, GPUImageView:用于顯示到屏幕上, 或者GPUImageMovieWriter:寫成視頻文件。
- 一般的target可分為兩類
- GPUImage處理主要分為3個(gè)環(huán)節(jié)
- source(視頻旋奢、圖片源) -> filter(濾鏡) -> final target (處理后視頻泳挥、圖片)
- GPUImaged的Source:都繼承GPUImageOutput的子類,作為GPUImage的數(shù)據(jù)源,就好比外界的光線至朗,作為眼睛的輸出源
- GPUImageVideoCamera:用于實(shí)時(shí)拍攝視頻
- GPUImageStillCamera:用于實(shí)時(shí)拍攝照片
- GPUImagePicture:用于處理已經(jīng)拍攝好的圖片屉符,比如png,jpg圖片
- GPUImageMovie:用于處理已經(jīng)拍攝好的視頻,比如mp4文件
- GPUImage的filter:GPUimageFilter類或者子類,這個(gè)類繼承自 GPUImageOutput,并且遵守GPUImageInput協(xié)議锹引,這樣既能流進(jìn)矗钟,又能流出,就好比我們的墨鏡嫌变,光線通過墨鏡的處理吨艇,最終進(jìn)入我們眼睛
- GPUImage的final target:GPUImageView,GPUImageMovieWriter就好比我們眼睛,最終輸入目標(biāo)初澎。
美顏原理
- 磨皮(GPUImageBilateralFilter):本質(zhì)就是讓像素點(diǎn)模糊秸应,可以使用高斯模糊虑凛,但是可能導(dǎo)致邊緣會(huì)不清晰,用雙邊濾波(Bilateral Filter) 软啼,有針對(duì)性的模糊像素點(diǎn)桑谍,能保證邊緣不被模糊。
- 美白(GPUImageBrightnessFilter):本質(zhì)就是提高亮度祸挪。
GPUImage實(shí)戰(zhàn)
GPUImage原生美顏
步驟一:使用Cocoapods導(dǎo)入GPUImage
步驟二:創(chuàng)建視頻源GPUImageVideoCamera
步驟三:創(chuàng)建最終目的源:GPUImageView
步驟四:創(chuàng)建濾鏡組(GPUImageFilterGroup)锣披,需要組合亮度(GPUImageBrightnessFilter)和雙邊濾波(GPUImageBilateralFilter)這兩個(gè)濾鏡達(dá)到美顏效果.
步驟五:設(shè)置濾鏡組鏈
步驟六:設(shè)置GPUImage處理鏈,從數(shù)據(jù)源 => 濾鏡 => 最終界面效果
步驟七:開始采集視頻
注意點(diǎn):SessionPreset最好使用AVCaptureSessionPresetHigh贿条,會(huì)自動(dòng)識(shí)別雹仿,如果用太高分辨率,當(dāng)前設(shè)備不支持會(huì)直接報(bào)錯(cuò)
GPUImageVideoCamera必須要強(qiáng)引用整以,否則會(huì)被銷毀胧辽,不能持續(xù)采集視頻.
必須調(diào)用startCameraCapture,底層才會(huì)把采集到的視頻源公黑,渲染到GPUImageView中邑商,就能顯示了。GPUImageBilateralFilter的distanceNormalizationFactor值越小凡蚜,磨皮效果越- 好,distanceNormalizationFactor取值范圍: 大于1人断。
- (void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建視頻源
// SessionPreset:屏幕分辨率,AVCaptureSessionPresetHigh會(huì)自適應(yīng)高分辨率
// cameraPosition:攝像頭方向
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
_videoCamera = videoCamera;
// 創(chuàng)建最終預(yù)覽View
GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:captureVideoPreview atIndex:0];
// 創(chuàng)建濾鏡:磨皮朝蜘,美白恶迈,組合濾鏡
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;
// 設(shè)置濾鏡組鏈
[bilateralFilter addTarget:brightnessFilter];
[groupFilter setInitialFilters:@[bilateralFilter]];
groupFilter.terminalFilter = brightnessFilter;
// 設(shè)置GPUImage響應(yīng)鏈,從數(shù)據(jù)源 => 濾鏡 => 最終界面效果
[videoCamera addTarget:groupFilter];
[groupFilter addTarget:captureVideoPreview];
// 必須調(diào)用startCameraCapture谱醇,底層才會(huì)把采集到的視頻源暇仲,渲染到GPUImageView中,就能顯示了枣抱。
// 開始采集視頻
[videoCamera startCameraCapture];
}
- (IBAction)brightnessFilter:(UISlider *)sender {
_brightnessFilter.brightness = sender.value;
}
- (IBAction)bilateralFilter:(UISlider *)sender {
// 值越小熔吗,磨皮效果越好
CGFloat maxValue = 10;
[_bilateralFilter setDistanceNormalizationFactor:(maxValue - sender.value)];
}
利用美顏濾鏡實(shí)現(xiàn)
步驟一:使用Cocoapods導(dǎo)入GPUImage
步驟二:導(dǎo)入GPUImageBeautifyFilter文件夾
步驟三:創(chuàng)建視頻源GPUImageVideoCamera
步驟四:創(chuàng)建最終目的源:GPUImageView
步驟五:創(chuàng)建最終美顏濾鏡:GPUImageBeautifyFilter
步驟六:設(shè)置GPUImage處理鏈,從數(shù)據(jù)源 => 濾鏡 => 最終界面效果
注意:切換美顏效果原理:移除之前所有處理鏈佳晶,重新設(shè)置處理鏈
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 創(chuàng)建視頻源
// SessionPreset:屏幕分辨率桅狠,AVCaptureSessionPresetHigh會(huì)自適應(yīng)高分辨率
// cameraPosition:攝像頭方向
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPresetHigh cameraPosition:AVCaptureDevicePositionFront];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
_videoCamera = videoCamera;
// 創(chuàng)建最終預(yù)覽View
GPUImageView *captureVideoPreview = [[GPUImageView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:captureVideoPreview atIndex:0];
_captureVideoPreview = captureVideoPreview;
// 設(shè)置處理鏈
[_videoCamera addTarget:_captureVideoPreview];
// 必須調(diào)用startCameraCapture,底層才會(huì)把采集到的視頻源轿秧,渲染到GPUImageView中中跌,就能顯示了。
// 開始采集視頻
[videoCamera startCameraCapture];
}
- (IBAction)openBeautifyFilter:(UISwitch *)sender {
// 切換美顏效果原理:移除之前所有處理鏈菇篡,重新設(shè)置處理鏈
if (sender.on) {
// 移除之前所有處理鏈
[_videoCamera removeAllTargets];
// 創(chuàng)建美顏濾鏡
GPUImageBeautifyFilter *beautifyFilter = [[GPUImageBeautifyFilter alloc] init];
// 設(shè)置GPUImage處理鏈漩符,從數(shù)據(jù)源 => 濾鏡 => 最終界面效果
[_videoCamera addTarget:beautifyFilter];
[beautifyFilter addTarget:_captureVideoPreview];
} else {
// 移除之前所有處理鏈
[_videoCamera removeAllTargets];
[_videoCamera addTarget:_captureVideoPreview];
}
}