获取IOS设备上相册里的图片,在平移/缩放/旋转等编辑操做后,调用内核绘制图片,保证视觉上其显示效果(图片位置和图片内容)不改变:objective-c
图片编辑
时,UIView接受手势,用UIKit实时展示图片的变换状态;编辑完成
时,将图片和变换矩阵传入内核,利用OpenGL绘制最终状态。UIKit和OpenGL的坐标系不相同:网络
在图片编辑
过程当中,响应手势并经过图片的center和transform动态更新显示;同时将全部图片的变换累积到一个变换矩阵imageTransform中;在编辑完成
时内核利用imageTransform将图片正确绘制。须要注意的是:code
center和transform是UIKit坐标系,imageTransform是OpenGL坐标系。orm
在进入图片编辑模块时,初始化imageTransform图片
self.imageTransform = CGAffineTransformIdentity;
响应pan手势。因为两个坐标系的Y轴方向相反,因此imageTransform累积平移变换时,须要将Y轴方向变化量取反:it
-(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); } }
UIView的缩放默认是以其中心点为固定点,因此imageTransform累积缩放变换时,须要先将图片移动到原点位置,进行缩放后再恢复:io
-(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; } }
在UIKit的坐标系中,由X轴正方向朝Y轴正方向旋转n弧度(视觉上是逆时针),至关于在OpenGL坐标系中由X轴正方向朝Y轴正方向旋转PI-n弧度(视觉上是顺时针)。此时获得的图片只是旋转角度正确了,最后还须要对图片进行相对于图片中心的翻转才能获得同样的图片内容。form
-(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; } }