【iOS動畫核心技術與案例實戰】iOS的GIF動畫效果實現

GIF在iOS中的使用場景

  GIF在iOS中的使用場景有如下三個方面。
(1)GIF圖片分解爲單幀圖片。
(2)一系列單幀圖片合成GIF圖片。
(3)iOS系統上展現GIF動畫效果。
  在GIF的合成和分解方面將會接觸到iOS圖像處理核心框架ImageIO,做爲iOS系統中圖像處理的核心框架,它爲咱們提供了各類豐富的API,本文將要實現的GIF分解與合成功能,經過ImageIO就能夠很方便地實現。GIF動畫展現效果將結合UIImageView和定時器,利用逐幀展現的方式爲你們呈現GIF動畫效果。算法

GIF分解單幀圖片

1 GIF圖片分解過程

  GIF分解爲單幀圖片的過程以下。
圖片描述
  整個過程劃分爲5個模塊、4個過程,分別以下。
(1)本地讀取GIF圖片,將其轉換爲NSdata數據類型。
(2)將NSData做爲ImageIO模塊的輸入。
(3)獲取ImageIO的輸出數據:UIImage。
(4)將獲取到的UIImage數據存儲爲JPG或者PNG格式保存到本地。
  在整個GIF圖片分解的過程當中,ImageIO是處理過程的核心部分。它負責對GIF文件格式進行解析,並將解析以後的數據轉換爲一幀幀圖片輸出。幸運的是咱們並非「輪子」的創造者,而是隻要使用輪子便可。因此在本書中咱們不去研究GIF分解合成算法的具體實現方式,而是將注意力聚焦在如何使用ImageIO框架實現須要的功能上。swift

2 GIF圖片分解代碼實現

  在正式分析代碼以前,先來看看整個工程的文件結構,如圖。
【圖2】
  源文件使用的是plane.gif文件。ViewController.swift文件中的viewDidLoad()方法中包含了GIF圖片分解爲單幀圖片並保存到本地的全部代碼。下面就結合「GIF分解爲單幀圖片的過程」來實現這一功能。
功能模塊一:讀取GIF文件並將之轉換爲NSdata類型。框架

1   let gifPath:NSString = Bundle.main.path(forResource: "plane", ofType: "gif")! as NSString
2   let gifData:Data = try! Data(contentsOf: URL(fileURLWithPath: gifPath as String))

  代碼第1行經過path方法獲取文件名爲plane、文件格式爲gif的文件地址。第2行獲取文件信息並加載到gifData(NSData類型)變量中。至此已經完成整個處理流程的第一個環節。
【圖3】
  功能模塊二:利用ImageIO框架,遍歷全部GIF子幀。須要注意的是使用ImageIO必須把讀取到的NSdata數據轉換爲ImageIO能夠處理的數據類型,這裏使用CGImageSourceRef實現。其相應功能模塊的處理流程以下所示。
【圖4】動畫

1   let gifDataSource:CGImageSource =
           CGImageSourceCreateWithData(gifData as CFData, nil)!
2    let gifImageCount:Int = CGImageSourceGetCount(gifDataSource)
3     for i in 0...gifImageCount-1{
            let imageref:CGImage? =CGImageSourceCreateImageAtIndex(gifDataSource, i, nil)
            let image:UIImage = UIImage(cgImage: imageref!,scale:UIScreen.main.scale,orientation:UIImageOrientation.up )
        }

  下面是GIF數據處理流程中ImageIO部分功能描述。代碼第1行實現將GIF原始數據類型NSdata轉換爲ImageIO能夠直接處理的數據類型CGImageSourceRef。第2行獲取當前GIF圖片的分幀個數。咱們知道GIF圖片都是由一幀幀圖片組成的,那麼這一行就是爲了獲取構成GIF圖片的張數。第3行對CGImageSource數據按照圖片的序號進行遍歷,將遍歷出的結果使用UIImage系統方法將之轉換爲UIImage。
  這裏重點爲你們介紹兩種方法。
  CGImageSourceCreateImageAtIndex方法的做用是返回GIF中其中某一幀圖像的CGImage類型數據。該方法有三個參數,參數1爲GIF原始數據,參數2 爲GIF子幀中的序號(該序號從0開始),參數3爲GIF數據提取的一些選擇參數,由於這裏不是很經常使用,因此設置爲nil。spa

public func CGImageSourceCreateImageAtIndex(_ isrc: CGImageSource, _ index: Int, _ options: CFDictionary?) -> CGImage?

  如下爲UIImage類的方法,這個方法用於實例化UIImage實例對象。該方法有三個參數,參數1爲須要構建UIImage的內容,注意這裏的內容是CGImage類型,參數2爲手機物理像素與手機和手機顯示分辨率的換算係數,參數3代表構建的UIImage的圖像方向。經過這個方法就能夠在某種手機分辨率下構建指定方向的圖像,固然圖像的類型是UIImage類型。.net

public init(CGImage cgImage: CGImage, scale: CGFloat, orientation: UIImageOrientation)

  經過上述兩步已經獲取了UIImage,然而UIImage並非一般咱們看到的圖像格式,此圖像格式最大的特色是沒法存儲爲本地能夠查看的圖片格式,所以若是須要將圖像保存在本地,就須要在這以前將已經獲得的UIImage數據類型轉換爲PNG或者JPG類型的圖像數據,而後才能把圖像存儲到本地。code

閱讀全文直接點擊:http://click.aliyun.com/m/10018/對象

相關文章
相關標籤/搜索