OpenGLES渲染
OpenGLES渲染
OpenGLES使用GPU渲染图片,不占用CPU,但其使用还是挺复杂的.
先用OpenGLES显示一张图片:
- //
- // ShowViewController.m
- // OpenGLES
- //
- // Copyright (c) 2014年 Y.X. All rights reserved.
- //
- #import "ShowViewController.h"
- #import <GLKit/GLKit.h>
- #import <CoreImage/CoreImage.h>
- @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(, , 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 <GLKit/GLKit.h>
- #import <CoreImage/CoreImage.h>
- #import <QuartzCore/QuartzCore.h>
- @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(, ,
- [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:@ 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(, , , )];
- [self.view addSubview:slider];
- [slider addTarget:self
- action:@selector(event:)
- forControlEvents:UIControlEventValueChanged];
- slider.minimumValue = ;
- slider.maximumValue = ;
- }
- - (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 <UIKit/UIKit.h>
- #import <GLKit/GLKit.h>
- #import <CoreImage/CoreImage.h>
- @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 <CoreImage/CoreImage.h>
- #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(, , 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:@ forKey:kCIInputIntensityKey];
- // 初始化一个UISlider
- UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
- [self.view addSubview:slider];
- [slider addTarget:self
- action:@selector(event:)
- forControlEvents:UIControlEventValueChanged];
- slider.minimumValue = ;
- slider.maximumValue = ;
- }
- - (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 <CoreImage/CoreImage.h>
- #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(, , 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:@.f forKey:kCIInputIntensityKey];
- _ciFilter2 = [CIFilter filterWithName:@"CIHueAdjust"];
- [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];
- [_ciFilter2 setValue:@.f forKeyPath:kCIInputAngleKey];
- // 初始化UISlider
- _slider1 = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
- [self.view addSubview:_slider1];
- [_slider1 addTarget:self
- action:@selector(event1:)
- forControlEvents:UIControlEventValueChanged];
- _slider1.minimumValue = ;
- _slider1.maximumValue = ;
- _slider1.value = 0.5f;
- _slider2 = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
- [self.view addSubview:_slider2];
- [_slider2 addTarget:self
- action:@selector(event2:)
- forControlEvents:UIControlEventValueChanged];
- _slider2.minimumValue = -3.14f;
- _slider2.maximumValue = +3.14f;
- _slider2.value = .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
OpenGLES渲染的更多相关文章
- 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片
上一篇文章 实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 演示了如何将视频文件转换为yuv文件保存,现在要做的是如何将yuv文件利用OpenGLES渲染展示出图像画面.要将 ...
- iOS给图片添加滤镜&使用openGLES动态渲染图片
给图片增加滤镜有这两种方式: CoreImage / openGLES 下面先说明如何使用CoreImage给图片添加滤镜, 主要为以下步骤: #1.导入CIImage格式的原始图片 #2.创建CIF ...
- 将Cocos2dX渲染到MFC窗口上
引用:http://www.cnblogs.com/windeer/archive/2012/11/18/2767750.html 引言 现在智能手机已经慢慢进入大众化,移动类应用开始火爆起来,游戏类 ...
- iOS CoreImage图片处理动态渲染(滤镜)
// // ViewController.m // CoreImageOfDong // // Created by Dong on 15/6/30. // Copyright (c) 201 ...
- 实战FFmpeg + OpenGLES--iOS平台上视频解码和播放
一个星期的努力终于搞定了视频的播放,利用FFmpeg解码视频,将解码的数据通过OpenGLES渲染播放.搞清楚了自己想知道的和完成了自己的学习计划,有点小兴奋.明天就是“五一”,放假三天,更开心啦. ...
- CoreImage 处理图片
1.CoreImage 滤镜的使用(马赛克模糊) CoreImage是苹果公司为了简化图片处理的难度而开发出来的类库. 随着iOS版本号升级以及硬件性能的不断提升,CoreImage将支持越来越多的滤 ...
- iOS动画技术笔记
概述 在IOS开发中,实现动画操作的地方有很多,典型的是在视图控制器的segue操作时.在同一个视图控制器类中,加载切换不同的视图时,也需要动画效果,还有一些视图对象有动画效果会更好. 插一句,在IO ...
- Android Camera2 Opengles2.0 实时滤镜(冷暖色/放大镜/模糊/美颜)
https://blog.csdn.net/keen_zuxwang/article/details/78363464 demo: http://download.csdn.net/download/ ...
- OpenGL绘制一个三角形
应该建立一个vertex shader文件和一个pixel shader文件,分别命名为shader.vsh和shader.fsh. shader.vsh: attribute vec3 positi ...
随机推荐
- LDAP落地实战(一):OpenLDAP部署及管理维护
公司内部会有许多第三方系统或服务,例如Svn,Git,VPN,Jira,Jenkins等等,每个系统都需要维护一份账号密码以支持用户认证,当然公司也会有许多的主机或服务器,需要开放登录权限给用户登录使 ...
- facebook 摘要生成阅读笔记(二) Abstractive Sentence Summarization with Attentive Recurrent Neural Networks
整体流程与第一篇差不多,只是在encoder和decoder加入了RNN Encoder: 1. ai=xi+li ai=词向量+词在序列中的位置信息(相当于一个权重,[M, 1]) 流程: 先是CN ...
- Python远程连接主机之paramiko模块
Python的paramiko模块能够连接远程主机,并在该主机上执行命令,和该主机之间进行文件传输.paramiko支持用明文密码登录远程主机和秘钥登录.使用之前要安装一下这个模块哈,pip inst ...
- PTA (Advanced Level) 1021 Deepest Root
Deepest Root A graph which is connected and acyclic can be considered a tree. The hight of the tree ...
- 【BI】资料收集
从无到有--什么是BI 什么是BI(Business Intelligence) - @我爱菊花 - 博客园 http://www.cnblogs.com/jiesin/archive/2008/06 ...
- Python---战机小游戏,学习pygame
import pygame # 导入游戏包 pygame.init() # 导入并初始化所有pygame模块,使用其他模块之前必须先调用init()方法 print('下面是游戏代码:') # 绘制矩 ...
- *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<WKWebViewConfiguration 0x1701bcd20> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the k
问题描述: ionic项目,windows下正常,打包android可正常运行: 因为需要打包到iPhone (ios 11.0.1)上测试,将代码拿到Mac OS环境下(重新npm install. ...
- .net core 2.2 部署CentOS7(5)部署.net core mvc
目录: .net core 2.2 部署CentOS7(1)安装虚拟机 .net core 2.2 部署CentOS7(2)给虚拟机安装CentOS7 .net core 2.2 部署CentOS7( ...
- spring jpa和mybatis整合
spring jpa和mybatis整合 前一阵子接手了一个使用SpringBoot 和spring-data-jpa开发的项目 后期新加入一个小伙伴,表示jpa相比mybatis太难用,多表联合的查 ...
- Java生成xlsx格式的excel文件
xlsx格式的写入的数据量据说有百万级,结合实际需要该格式. public static void main(String[] args) throws Exception { OutputStrea ...