1.CoreImage 滤镜的使用(马赛克模糊)
CoreImage是苹果公司为了简化图片处理的难度而开发出来的类库。
随着iOS版本升级以及硬件性能的不断提升,CoreImage将支持越来越多的滤镜
- (void)hFilter {
// 0.
导入CIImage图片
CIImage *ciImage = [[CIImage
alloc] initWithImage:[UIImage
imageNamed:@"demo"]];
// 1.
创建出Filter滤镜
CIFilter *filter = [CIFilter
filterWithName:@"CIPixellate"];
[filter
setValue:ciImage
forKey:kCIInputImageKey];
NSLog(@"%@", filter.attributes);
[filter
setDefaults];
CIImage *outImage = [filter
valueForKey:kCIOutputImageKey];
// 2.
用CIContext将滤镜中的图片渲染出来
CIContext *context = [CIContext
contextWithOptions:nil];
CGImageRef cgImage = [context
createCGImage:outImage
fromRect:[outImage
extent]];
// 3.
导出图片
UIImage *showImage = [UIImage
imageWithCGImage:cgImage];
CGImageRelease(cgImage);
// 4.
加载出来
UIImageView *imageView = [[UIImageView
alloc] initWithImage:showImage];
imageView.center =
self.view.center;
[self.view
addSubview:imageView];
}
不同的滤镜可以组合在一起使用。
可以动态的修改滤镜组合中单个滤镜的参数来实现一种动态调整的效果
- (void)complexCoreImage {
// 0.
导入CIImage图片
CIImage *ciImage = [[CIImage
alloc] initWithImage:[UIImage
imageNamed:@"demo"]];
// 1.
创建出Filter滤镜
CIFilter *filterOne = [CIFilter
filterWithName:@"CIPixellate"];
[filterOne
setValue:ciImage
forKey:kCIInputImageKey];
[filterOne
setDefaults];
CIImage *outImage = [filterOne
valueForKey:kCIOutputImageKey];
CIFilter *filterTwo = [CIFilter
filterWithName:@"CIHueAdjust"];
[filterTwo
setValue:outImage
forKey:kCIInputImageKey];
[filterTwo
setDefaults];
//默认为0,不设置不能改变,可以封装一个调用
[filterTwo
setValue:@(3.14)
forKey:kCIInputAngleKey];
NSLog(@"%@",filterTwo.attributes);//可以看到一些参数 key
CIImage *outputImage = [filterTwo
valueForKey:kCIOutputImageKey];
// 2.
用CIContext将滤镜中的图片渲染出来
CIContext *context = [CIContext
contextWithOptions:nil];
CGImageRef cgImage = [context
createCGImage:outputImage
fromRect:[outImage
extent]];
// 3.
导出图片
UIImage *showImage = [UIImage
imageWithCGImage:cgImage];
CGImageRelease(cgImage);
// 4.
加载出来
UIImageView *imageView = [[UIImageView
alloc] initWithImage:showImage];
imageView.center =
self.view.center;
[self.view
addSubview:imageView];
}
3.在 OpenGLES 下进行渲染
在OpenGLES下进行滤镜的渲染可以提高效率。(GPU渲染,不占用CPU)
如果需要实时查看多个滤镜动态渲染的效果,使用OpenGLES是一个好的选择
#import <GLKit/GLKit.h>
@interface
ViewController ()
@property (nonatomic,
strong) GLKView *glkView;
// 渲染用的buffer视图
@property (nonatomic,
strong) CIFilter *filter;
@property (nonatomic,
strong) CIImage *ciImage;
@property (nonatomic,
strong) CIContext *ciContext;
@end
@implementation ViewController
- (void)viewDidLoad {
[super
viewDidLoad];
UIImage *showImage = [UIImage
imageNamed:@"demo"];
CGRect rect =
CGRectMake(0,
0, showImage.size.width, showImage.size.height);
//
获取OpenGLES渲染的上下文
EAGLContext *eagContext = [[EAGLContext
alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
//
创建出渲染的buffer
_glkView = [[GLKView
alloc] initWithFrame:rect
context:eagContext];
[_glkView
bindDrawable];
[self.view
addSubview:_glkView];
//
创建出CoreImage用的上下文
_ciContext = [CIContext
contextWithEAGLContext:eagContext
options:@{kCIContextWorkingColorSpace : [NSNull
null]}];
// CoreImage相关设置
_ciImage = [[CIImage
alloc] initWithImage:showImage];
_filter = [CIFilter
filterWithName:@"CISepiaTone"];
[_filter
setValue:_ciImage
forKey:kCIInputImageKey];
[_filter
setValue:@(0)
forKey:kCIInputIntensityKey];
//
开始渲染
[_ciContext
drawImage:[_filter
outputImage]
inRect:CGRectMake(0,
0, _glkView.drawableWidth,
_glkView.drawableHeight)
fromRect:[_ciImage
extent]];
[_glkView
display];
//
动态渲染
UISlider *slider = [[UISlider
alloc] initWithFrame:CGRectMake(0,
400, 320,
20)];
slider.minimumValue =
0.f;
slider.maximumValue =
1.f;
[slider addTarget:self
action:@selector(sliderEvent:)
forControlEvents:UIControlEventValueChanged];
[self.view
addSubview:slider];
}
- (void)sliderEvent:(UISlider *)slider {
[_filter
setValue:_ciImage
forKey:kCIInputImageKey];
[_filter
setValue:@(slider.value)
forKey:kCIInputIntensityKey];
//
开始渲染
[_ciContext
drawImage:[_filter
outputImage]
inRect:CGRectMake(0,
0, _glkView.drawableWidth,
_glkView.drawableHeight)
fromRect:[_ciImage
extent]];
[_glkView
display];
}
版权声明:本文为博主原创文章,未经博主允许不得转载。