獲取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; } }