有時候我們需要對圖片(UIImage)進行垂直翻轉(上下翻轉),或者水平翻轉處理(即鏡像處理)。如下圖:
通常有兩種方式。
方法一,更改圖片方向
1,實現原理
UIImage 有個屬性叫 imageOrientation,它是一個枚舉變量。主要作用是控制image的繪制方向,共有以下8種方向:
enum UIImageOrientation : Int {
case Up //0:默認方向
case Down //1:180°旋轉
case Left //2:逆時針旋轉90°
case Right //3:順時針旋轉90°
case UpMirrored //4:水平翻轉
case DownMirrored //5:水平翻轉
case LeftMirrored //6:垂直翻轉
case RightMirrored //7:垂直翻轉
}
那麼我們只需要通過改變 UIImage 的 orientation,這樣圖片顯示出來的時候,圖片容器會根據新的這個 orientation 屬性進行顯示。從而實現水平翻轉或者垂直翻轉。
2,水平翻轉(即左右鏡像)
//原始圖片
let srcImage = UIImage(named: "hangge.png")!
//翻轉圖片的方向
let flipImageOrientation = (srcImage.imageOrientation.rawValue + 4) % 8
//翻轉圖片
let flipImage = UIImage(CGImage:srcImage.CGImage!,
scale:srcImage.scale,
orientation:UIImageOrientation(rawValue: flipImageOrientation)!
)
//圖片顯示
imageView.image = flipImage
3,垂直翻轉
//原始圖片
let srcImage = UIImage(named: "hangge.png")!
//翻轉圖片的方向
var flipImageOrientation = (srcImage.imageOrientation.rawValue + 4) % 8
flipImageOrientation += flipImageOrientation%2==0 ? 1 : -1
//翻轉圖片
let flipImage = UIImage(CGImage:srcImage.CGImage!,
scale:srcImage.scale,
orientation:UIImageOrientation(rawValue: flipImageOrientation)!
)
//圖片顯示
imageView.image = flipImage
方法二,通過Quartz重繪圖片,改變原始圖片數據
1,實現原理
方法1是通過改變 UIImage 的 orientation 實現翻轉的,也就是說它只是改變了一個標記而已。
它內部的圖片數據其實還是原始的數據,如果翻轉圖片不是用來顯示,而是需要用於圖像識別、圖像處理等操作那上面那個方法就不適合了。
本方法是將 UIImage 的圖片原始數據數組進行重排,從而實現翻轉。其實現的關鍵點是在Core Graphics(Quartz)層面上重繪圖片。
2,水平翻轉(即左右鏡像)
由於Core Graphics(Quartz) 與 UIKit 的y軸坐標系是相反的,先繞原點旋轉180度,再平移一下就好了
//原始圖片
let srcImage = UIImage(named: "hangge.png")!
//Quartz重繪圖片
let rect = CGRectMake(0, 0, srcImage.size.width , srcImage.size.height);//創建矩形框
//根據size大小創建一個基於位圖的圖形上下文
UIGraphicsBeginImageContextWithOptions(rect.size, false, 2)
let currentContext = UIGraphicsGetCurrentContext();//獲取當前quartz 2d繪圖環境
CGContextClipToRect(currentContext, rect);//設置當前繪圖環境到矩形框
CGContextRotateCTM(currentContext, CGFloat(M_PI)); //旋轉180度
//平移, 這裡是平移坐標系,跟平移圖形是一個道理
CGContextTranslateCTM(currentContext, -rect.size.width, -rect.size.height);
CGContextDrawImage(currentContext, rect, srcImage.CGImage);//繪圖
//翻轉圖片
let drawImage = UIGraphicsGetImageFromCurrentImageContext();//獲得圖片
let flipImage = UIImage(CGImage:drawImage.CGImage!,
scale:srcImage.scale,
orientation:srcImage.imageOrientation //圖片方向不用改
)
//圖片顯示
imageView.image = flipImage
3,垂直翻轉
垂直翻轉更簡單了。由於 Core Graphics(Quartz) 與 UIKit 的y軸坐標系是相反的,UIKit是y軸向下,Quartz是y軸向上。直接繪制就是垂直翻轉的。
//原始圖片
let srcImage = UIImage(named: "hangge.png")!
//Quartz重繪圖片
let rect = CGRectMake(0, 0, srcImage.size.width , srcImage.size.height);//創建矩形框
//根據size大小創建一個基於位圖的圖形上下文
UIGraphicsBeginImageContextWithOptions(rect.size, false, 2)
let currentContext = UIGraphicsGetCurrentContext();//獲取當前quartz 2d繪圖環境
CGContextClipToRect(currentContext, rect);//設置當前繪圖環境到矩形框
CGContextDrawImage(currentContext, rect, srcImage.CGImage);//繪圖
//翻轉圖片
let drawImage = UIGraphicsGetImageFromCurrentImageContext();//獲得圖片
let flipImage = UIImage(CGImage:drawImage.CGImage!,
scale:srcImage.scale,
orientation:srcImage.imageOrientation //圖片方向不用改
)
//圖片顯示
imageView.image = flipImage
注:如何防止由於圖片重繪造成顯示模糊
由於使用視網膜屏,我的原始圖片是 [email protected]。如果使用第二方法,即通過重繪來實現圖片翻轉並顯示出來。那麼在創建圖形上下文的時候就需要設置好放大倍數。而不能簡單地直接 UIGraphicsBeginImageContext(rect.size) 來創建。
//根據size大小創建一個基於位圖的圖形上下文
UIGraphicsBeginImageContextWithOptions(rect.size, false, 2)