博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用UIView上手势控制OpenGL的绘制
阅读量:6388 次
发布时间:2019-06-23

本文共 2950 字,大约阅读时间需要 9 分钟。

hot3.png

场景

获取IOS设备上相册里的图片,在平移/缩放/旋转等编辑操作后,调用内核绘制图片,保证视觉上其显示效果(图片位置和图片内容)不改变:

  • 图片编辑时,UIView接受手势,用UIKit实时展现图片的变换状态;
  • 编辑完成时,将图片和变换矩阵传入内核,利用OpenGL绘制最终状态。

问题

UIKitOpenGL的坐标系不相同:

  • UIKit的坐标系:以左上角为原点,X轴向右,Y轴向下(右图);
  • OpenGL的坐标系:以左下角为原点,X轴向右,Y轴向上(左图); 图片来源于网络

解决方案

图片编辑过程中,响应手势并通过图片的centertransform动态更新显示;同时将所有图片的变换累积到一个变换矩阵imageTransform中;在编辑完成时内核利用imageTransform将图片正确绘制。需要注意的是:

centertransformUIKit坐标系,imageTransformOpenGL坐标系。

1.初始化

在进入图片编辑模块时,初始化imageTransform

self.imageTransform = CGAffineTransformIdentity;

2.平移

响应pan手势。由于两个坐标系的Y轴方向相反,所以imageTransform累积平移变换时,需要***将Y轴方向变化量取反***:

-(void)panImage:(UIPanGestureRecognizer*)pan {	if (pan.state == UIGestureRecognizerStateChanged) {  		/// 改变图片显示状态  		CGPoint loc = [pan translationInView:self.view];  		[pan setTranslation:CGPointZero inView:self.view];  		self.imageView.center = CGPointMake(self.imageView.center.x+loc.x, self.imageView.center.y+loc.y);  		/// 累积平移矩阵  		CGAffineTransform tX = CGAffineTransformIdentity;  		tX = CGAffineTransformTranslate(tX, loc.x, -loc.y);  		self.imageTransform = CGAffineTransformConcat(self.imageTransform, tX);  	}}

3.缩放

UIView的缩放默认是以其中心点为固定点,所以imageTransform累积缩放变换时,需要***先将图片移动到原点位置,进行缩放后再恢复***:

-(void)pinchImage:(UIPinchGestureRecognizer*)pinch{        if (pinch.state == UIGestureRecognizerStateChanged) {		/// 改变图片显示状态        self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);        	    	/// 累积平移矩阵    	CGPoint pivot = self.imageView.center;        pivot.y = self.view.bounds.size.height - pivot.y;        CGAffineTransform tX = CGAffineTransformIdentity;         tX = CGAffineTransformIdentity;        tX = CGAffineTransformTranslate(tX, pivot.x, pivot.y);        tX = CGAffineTransformScale(tX, pinch.scale, pinch.scale);        tX = CGAffineTransformTranslate(tX, -pivot.x, -pivot.y)        self.imageTransform = CGAffineTransformConcat(self.imageTransform, tX);  		/// 充值缩放因子        pinch.scale = 1;    }}

4.旋转

在UIKit的坐标系中,由X轴正方向朝Y轴正方向旋转n弧度(视觉上是逆时针),相当于在OpenGL坐标系中由X轴正方向朝Y轴正方向旋转PI-n弧度(视觉上是顺时针)。此时得到的图片只是旋转角度正确了,最后还需要对图片进行相对于图片中心的翻转才能得到一样的图片内容。

-(void)rotateImage:(UIRotationGestureRecognizer*)rotate{        if (rotate == UIGestureRecognizerStateChanged) {        /// 改变图片显示状态        CGFloat angle = rotate.rotation;        self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, angle);                /// 累积平移矩阵        CGPoint pivot = self.imageView.center;        pivot.y = self.view.bounds.size.height - pivot.y;        CGAffineTransform tX = CGAffineTransformIdentity;        tX = CGAffineTransformTranslate(tX, pivot.x, pivot.y);        tX = CGAffineTransformRotate(tX, M_PI-angle);        tX = CGAffineTransformScale(tX, -1, -1);	//中心翻转        tX = CGAffineTransformTranslate(tX, -pivot.x, -pivot.y);        self.imageTransform = CGAffineTransformConcat(self.imageTransform, tX);                // 重置旋转角度        rotate.rotation = 0;      }}

转载于:https://my.oschina.net/chicboi/blog/510518

你可能感兴趣的文章
Win32编程基本概念
查看>>
×××灯式样的站点链接说明,链接提示
查看>>
Linux下动态IP和静态IP的设置方法
查看>>
mysql 行长度
查看>>
SUSE配置网关
查看>>
java中获取字母和数字的组合
查看>>
8-3 泛型
查看>>
你是“职业”软件开发吗?——书评《浮现式设计-专业软件开发的演进本质》...
查看>>
iOS 多线程 之 GCD(大中枢派发)(二)
查看>>
开源项目 log4android 使用方式详解
查看>>
ssh命令详解
查看>>
C# 中字符串转换成日期
查看>>
垃圾短信相关用户细分方案
查看>>
免费的Windows系统工具
查看>>
脚本:将git项目下载到本地并启动
查看>>
Linked List Cycle && Linked List Cycle II
查看>>
SeleniumTest
查看>>
ubuntu10.04 交叉编译 aria2 总结
查看>>
实验二 linux常用命令练习
查看>>
SPY
查看>>