iOS从零开始学习直播之3.美颜
任何一款直播软件都必须进行美颜,不然哪来的那么多美女,所以技术改变世界,不只是说说而已。美颜在采集的时候就得就行,让主播实时看到直播的效果。
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文件夹里,重新打开就可以运行了。

iOS从零开始学习直播之3.美颜的更多相关文章
- iOS从零开始学习直播之2.采集
直播的采集由采集的设备(摄像头.话筒)不同分为视频采集和音频采集,本篇文章会分别介绍. 1.采集步骤 1.创建捕捉会话(AVCaptureSession),iOS调用相机和话筒之前都需要创建捕 ...
- iOS从零开始学习直播之1.播放
对于直播来说,客户端主要做两件事情,推流和播放.今天先讲播放. 播放流程 1.拉流:服务器已有直播内容,从指定地址进行拉取的过程.其实就是向服务器请求数据. 2.解码:对视屏数据进行解压缩. 3. ...
- iOS从零开始学习直播之音频1.播放本地音频文件
现在直播越来越火,俨然已经成为了下一个红海.作为一个资深码农(我只喜欢这样称呼自己,不喜欢别人这样称呼我),我必须赶上时代的潮流,开始研究视频直播.发现视屏直播类的文章上来就讲拉流.推流.采集.美 ...
- iOS从零开始学习直播之音频4.歌词
上一篇讲了歌曲的切换,这一篇主要讲歌词部分的实现. 先看效果图.当歌手唱到这句歌词时候,我们要标记出来,这里显示字体为黄色. 1.获取歌词 一般歌词都是一个链接.类似于"http ...
- iOS从零开始学习直播之音频3.歌曲切换
上周迟到了,周末去参加OSC源创会了,还是有点启发的.但这不是重点,重点是 上一篇我只是实现了一首歌曲的在线播放,这肯定是不够的.这一篇博客主要是实现了多首歌曲的顺序播放以及上一首和下一首切换. ...
- iOS从零开始学习直播之音频2.后台播放和在线播放
本篇主要讲音频的后台播放和在线播放. 后台播放 上一篇写的工程运行之后程序退至后台,发现运行不了,歌停止了,这显然不行,音乐后台播放是标配啊.今天就来讲一下后台播放. 1.在plist文件里,告诉 ...
- 【如何快速的开发一个完整的iOS直播app】(美颜篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,美颜功能是很重 ...
- 【如何快速的开发一个完整的 iOS 直播 app】(美颜篇)
来源:袁峥Seemygo 链接:http://www.jianshu.com/p/4646894245ba 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播 ...
- 从零开始学习CocoaPods安装和使用
从零开始学习CocoaPods安装和使用 转载: Code4App原创:http://code4app.com/article/cocoapods-install-usage http://m.i ...
随机推荐
- git-简单流程(学习笔记)
这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...
- [APUE]UNIX进程的环境(下)
一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函 ...
- 前端框架 EasyUI (0) 重新温习(序言)
几年前,参与过一个项目.那算是一个小型的信息管理系统,BS 结构的,前端用的是基于 jQuery 的 EasyUI 框架. 我进 Team 的时候,项目已经进入开发阶段半个多月了.听说整个项目的框架是 ...
- CENTOS 6.5 平台离线编译安装 PHP5.6.6
一.下载php源码包 http://cn2.php.net/get/php-5.6.6.tar.gz/from/this/mirror 二.编译 编译之前可能会缺少一些必要的依赖包,加载一个本地yum ...
- zookeeper源码分析之六session机制
zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...
- openresty 前端开发入门四之Redis篇
这章主要演示怎么通过lua连接redis,并根据用户输入的key从redis获取value,并返回给用户 操作redis主要用到了lua-resty-redis库,代码可以在github上找得到 而且 ...
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...
- AFNetworking报错"_UTTypeCopyPreferredTagWithClass", referenced from: _AFContentTypeForPathExtens
问题: 在和Unity交互的过程中,从Unity开发工具打包出来的项目文件,在添加AFNetworking库,运行时报出以下错误: Undefined symbols for architecture ...
- 14门Linux课程,打通你Linux的任督二脉!
Linux有很多优点:安全.自主.开源--,也正是这些优点使得很多人都在学Linux. 虽说网上有大把的Linux课程资源,但是对很多小白来说网上的课程资源比较零散并不适合新手学习. 正因为此,总结了 ...
- 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...