本文共 9804 字,大约阅读时间需要 32 分钟。
OpenGLES渲染
OpenGLES使用GPU渲染图片,不占用CPU,但其使用还是挺复杂的.
先用OpenGLES显示一张图片:
//// ShowViewController.m// OpenGLES//// Copyright (c) 2014年 Y.X. All rights reserved.//#import "ShowViewController.h"#import#import @interface ShowViewController ()@property (nonatomic, strong) GLKView *viewBuffer;@end@implementation ShowViewController- (void)viewDidLoad{ [super viewDidLoad]; // 获取OpenGLES渲染环境 EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; // 根据图片获取尺寸 UIImage *image = [UIImage imageNamed:@"demo.png"]; CIImage *ciimage = [[CIImage alloc] initWithImage:image]; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); // 初始化GLKView并指定OpenGLES渲染环境 _viewBuffer = [[GLKView alloc] initWithFrame:rect context:eaglContext]; [self.view addSubview:_viewBuffer]; // 与OpenGLES绑定 [_viewBuffer bindDrawable]; // 定义绘制区域(像素描述) CGRect rectInPixels = \ CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight); // 初始化CIImage的环境,指定在OpenGLES2上操作(此处只在GPU上操作) CIContext *context = \ [CIContext contextWithEAGLContext:eaglContext options:@{kCIContextWorkingColorSpace:[NSNull null]}]; // 开始绘制 [context drawImage:ciimage inRect:rectInPixels fromRect:[ciimage extent]]; // 显示 [_viewBuffer display];}@end
只是显示一张图片而已,就需要写这么多的代码-_-!!!!
他有什么优势呢?其实,它的优势是实时渲染图片,不卡的.
//// RootViewController.m// OpenGLES//// Copyright (c) 2014年 Y.X. All rights reserved.//#import "RootViewController.h"#import#import #import @interface RootViewController ()@property (nonatomic, strong) GLKView *viewBuffer;@property (nonatomic, strong) CIContext *ciContext;@property (nonatomic, strong) CIImage *ciImage;@property (nonatomic, strong) CIFilter *ciFilter;@end@implementation RootViewController- (void)viewDidLoad{ [super viewDidLoad]; // 获取OpenGLES2渲染环境 EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; // 初始化一个viewBuffer,并指定在OpenGLES2环境渲染 CGRect rect = CGRectMake(0, 0, [UIImage imageNamed:@"demo"].size.width, [UIImage imageNamed:@"demo"].size.height); _viewBuffer = [[GLKView alloc] initWithFrame:rect context:eaglContext]; // 绑定将这个view与OpenGLES2绑定 [_viewBuffer bindDrawable]; [self.view addSubview:_viewBuffer]; // 初始化CIImage的环境,指定在OpenGLES2上操作(此处只在GPU上操作) _ciContext = [CIContext contextWithEAGLContext:eaglContext options:@{kCIContextWorkingColorSpace:[NSNull null]}]; // 获取CIImage _ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"demo"]]; // 初始化一个CIFilter _ciFilter = [CIFilter filterWithName:@"CISepiaTone"]; [_ciFilter setValue:_ciImage forKey:kCIInputImageKey]; [_ciFilter setValue:@0 forKey:kCIInputIntensityKey]; // 定义绘制区域(像素描述) CGRect rectInPixels = \ CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight); // 开始绘制 [_ciContext drawImage:_ciImage inRect:rectInPixels fromRect:[_ciImage extent]]; [_viewBuffer display]; UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 400, 320, 20)]; [self.view addSubview:slider]; [slider addTarget:self action:@selector(event:) forControlEvents:UIControlEventValueChanged]; slider.minimumValue = 0; slider.maximumValue = 1;}- (void)event:(UISlider *)slider{ [_ciFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:kCIInputIntensityKey]; // 定义绘制区域(像素描述) CGRect rectInPixels = \ CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight); [_ciContext drawImage:[_ciFilter outputImage] inRect:rectInPixels fromRect:[_ciImage extent]]; [_viewBuffer display];}@end
将这个View封装一下吧.
GPUView.h + GPUView.m
//// GPUView.h// OpenGLES//// Copyright (c) 2014年 Y.X. All rights reserved.//#import#import #import @interface GPUView : UIView- (void)drawCIImage:(CIImage *)ciImage;@end
//// GPUView.m// OpenGLES//// Copyright (c) 2014年 Y.X. All rights reserved.//#import "GPUView.h"@interface GPUView ()@property (nonatomic, assign) CGRect rectInPixels;@property (nonatomic, strong) CIContext *context;@property (nonatomic, strong) GLKView *showView;@end@implementation GPUView- (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { // 获取OpenGLES渲染环境 EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; // 初始化GLKView并指定OpenGLES渲染环境 + 绑定 _showView = [[GLKView alloc] initWithFrame:frame context:eaglContext]; [_showView bindDrawable]; // 添加进图层 [self addSubview:_showView]; // 创建CIContext环境 _context = \ [CIContext contextWithEAGLContext:eaglContext options:@{kCIContextWorkingColorSpace:[NSNull null]}]; // 定义绘制区域(像素描述) _rectInPixels = \ CGRectMake(0.0, 0.0, _showView.drawableWidth, _showView.drawableHeight); } return self;}- (void)drawCIImage:(CIImage *)ciImage{ // 开始绘制 [_context drawImage:ciImage inRect:_rectInPixels fromRect:[ciImage extent]]; // 显示 [_showView display];}@end实现同样的效果:
//// ShowViewController.m// OpenGLES//// Copyright (c) 2014年 Y.X. All rights reserved.//#import "ShowViewController.h"#import#import "GPUView.h"@interface ShowViewController ()@property (nonatomic, strong) CIFilter *ciFilter;@property (nonatomic, strong) GPUView *gpuView;@end@implementation ShowViewController- (void)viewDidLoad{ [super viewDidLoad]; // 根据图片获取尺寸 UIImage *image = [UIImage imageNamed:@"demo.png"]; CIImage *ciimage = [[CIImage alloc] initWithImage:image]; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); // 初始化GPUView _gpuView = [[GPUView alloc] initWithFrame:rect]; [self.view addSubview:_gpuView]; [_gpuView drawCIImage:ciimage]; // 初始化一个CIFilter _ciFilter = [CIFilter filterWithName:@"CISepiaTone"]; [_ciFilter setValue:ciimage forKey:kCIInputImageKey]; [_ciFilter setValue:@0 forKey:kCIInputIntensityKey]; // 初始化一个UISlider UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 400, 320, 20)]; [self.view addSubview:slider]; [slider addTarget:self action:@selector(event:) forControlEvents:UIControlEventValueChanged]; slider.minimumValue = 0; slider.maximumValue = 1;}- (void)event:(UISlider *)slider{ [_ciFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:kCIInputIntensityKey]; [_gpuView drawCIImage:[_ciFilter outputImage]];}@end
看起来简洁多了.....
来点复杂点的,同时操作两个滤镜
//// ShowViewController.m// OpenGLES//// Copyright (c) 2014年 Y.X. All rights reserved.//#import "ShowViewController.h"#import#import "GPUView.h"@interface ShowViewController ()@property (nonatomic, strong) CIFilter *ciFilter1;@property (nonatomic, strong) CIFilter *ciFilter2;@property (nonatomic, strong) GPUView *gpuView;@property (nonatomic, strong) UISlider *slider1;@property (nonatomic, strong) UISlider *slider2;@end@implementation ShowViewController- (void)viewDidLoad{ [super viewDidLoad]; // 根据图片获取尺寸 UIImage *image = [UIImage imageNamed:@"demo.png"]; CIImage *ciimage = [[CIImage alloc] initWithImage:image]; CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height); // 初始化GPUView _gpuView = [[GPUView alloc] initWithFrame:rect]; [self.view addSubview:_gpuView]; [_gpuView drawCIImage:ciimage]; // 初始化一个CIFilter _ciFilter1 = [CIFilter filterWithName:@"CISepiaTone"]; [_ciFilter1 setValue:ciimage forKey:kCIInputImageKey]; [_ciFilter1 setValue:@0.f forKey:kCIInputIntensityKey]; _ciFilter2 = [CIFilter filterWithName:@"CIHueAdjust"]; [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey]; [_ciFilter2 setValue:@0.f forKeyPath:kCIInputAngleKey]; // 初始化UISlider _slider1 = [[UISlider alloc] initWithFrame:CGRectMake(0, 400, 320, 20)]; [self.view addSubview:_slider1]; [_slider1 addTarget:self action:@selector(event1:) forControlEvents:UIControlEventValueChanged]; _slider1.minimumValue = 0; _slider1.maximumValue = 1; _slider1.value = 0.5f; _slider2 = [[UISlider alloc] initWithFrame:CGRectMake(0, 450, 320, 20)]; [self.view addSubview:_slider2]; [_slider2 addTarget:self action:@selector(event2:) forControlEvents:UIControlEventValueChanged]; _slider2.minimumValue = -3.14f; _slider2.maximumValue = +3.14f; _slider2.value = 0.f;}- (void)event1:(UISlider *)slider{ [_ciFilter1 setValue:[NSNumber numberWithFloat:_slider1.value] forKey:kCIInputIntensityKey]; [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey]; [_ciFilter2 setValue:[NSNumber numberWithFloat:_slider2.value] forKeyPath:kCIInputAngleKey]; [_gpuView drawCIImage:[_ciFilter2 outputImage]];}- (void)event2:(UISlider *)slider{ [_ciFilter1 setValue:[NSNumber numberWithFloat:_slider1.value] forKey:kCIInputIntensityKey]; [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey]; [_ciFilter2 setValue:[NSNumber numberWithFloat:_slider2.value] forKeyPath:kCIInputAngleKey]; [_gpuView drawCIImage:[_ciFilter2 outputImage]];}@end
转载地址:http://lvdfx.baihongyu.com/