中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS的GIF動畫效果怎么實現

發布時間:2021-12-18 16:28:18 來源:億速云 閱讀:238 作者:柒染 欄目:互聯網科技

本篇文章給大家分享的是有關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分解為單幀圖片的過程如下。 
iOS的GIF動畫效果怎么實現
  整個過程劃分為5個模塊、4個過程,分別如下。 
(1)本地讀取GIF圖片,將其轉換為NSdata數據類型。 
(2)將NSData作為ImageIO模塊的輸入。 
(3)獲取ImageIO的輸出數據:UIImage。 
(4)將獲取到的UIImage數據存儲為JPG或者PNG格式保存到本地。 
  在整個GIF圖片分解的過程中,ImageIO是處理過程的核心部分。它負責對GIF文件格式進行解析,并將解析之后的數據轉換為一幀幀圖片輸出。幸運的是我們并不是“輪子”的創造者,而是只要使用輪子即可。所以在本書中我們不去研究GIF分解合成算法的具體實現方式,而是將注意力聚焦在如何使用ImageIO框架實現需要的功能上。

2 GIF圖片分解代碼實現

  在正式分析代碼之前,先來看看整個工程的文件結構,如圖。 
iOS的GIF動畫效果怎么實現
  源文件使用的是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類型)變量中。至此已經完成整個處理流程的第一個環節。 
iOS的GIF動畫效果怎么實現
  功能模塊二:利用ImageIO框架,遍歷所有GIF子幀。需要注意的是使用ImageIO必須把讀取到的NSdata數據轉換為ImageIO可以處理的數據類型,這里使用CGImageSourceRef實現。其相應功能模塊的處理流程如下所示。 
iOS的GIF動畫效果怎么實現

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。

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

  以下為UIImage類的方法,這個方法用于實例化UIImage實例對象。該方法有三個參數,參數1為需要構建UIImage的內容,注意這里的內容是CGImage類型,參數2為手機物理像素與手機和手機顯示分辨率的換算系數,參數3表明構建的UIImage的圖像方向。通過這個方法就可以在某種手機分辨率下構建指定方向的圖像,當然圖像的類型是UIImage類型。

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

  通過上述兩步已經獲取了UIImage,然而UIImage并不是通常我們看到的圖像格式,此圖像格式最大的特點是無法存儲為本地可以查看的圖片格式,因此如果需要將圖像保存在本地,就需要在這之前將已經得到的UIImage數據類型轉換為PNG或者JPG類型的圖像數據,然后才能把圖像存儲到本地。 
  下面是完整的GIF圖像分解保存代碼:

override func viewDidLoad() { 1 super.viewDidLoad() 2 let gifPath:NSString = Bundle.main.path(forResource:"plane", ofType: "gif")! as NSString 3 let gifData:Data = try! Data(contentsOf:URL(fileURLWithPath: gifPath as String)) 4 let gifDataSource:CGImageSource =CGImageSourceCreateWithData(gifData as CFData, nil)! 5 let gifImageCount:Int =CGImageSourceGetCount(gifDataSource) 6 for i in 0...gifImageCount-1{ 7 let imageref:CGImage? =CGImageSourceCreateImageAtIndex(gifDataSource, i, nil) 8 let image:UIImage = UIImage(cgImage: imageref!,scale:UIScreen.main.scale,orientation:UIImageOrientation.up ) 9 let imageData:Data = UIImagePNGRepresentation(image)! 10 var docs=NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 11 let documentsDirectory = docs[0] as String 12 let imagePath = documentsDirectory+"/\(i)"+".png" 13 try? imageData .write(to: URL(fileURLWithPath:imagePath), options: [.atomic]) 14 print("\(imagePath)")

        }
    }

  代碼第1行使用UIImagePNGRepresentation方法將UIImage數據類型存儲為PNG格式的data數據類型,第2行代碼和第3行代碼獲取應用的Document目錄,第4行調用write方法將圖片寫入到本地文件中。如果大家想查看最終寫入的效果,可以在最后一行添加print信息,將文件寫入路徑打印出來,觀察圖像寫入是否成功。

3 GIF圖片分解最終實現效果

  通過上述代碼中的最后一行print(“(imagePath)”)可以獲取圖片最終保存的路徑。進入該路徑下可以看到下圖所示的圖片最終分解結果。 
iOS的GIF動畫效果怎么實現

  根據上下圖,在Mac系統下,利用系統圖片的查看工具來查看GIF圖片的分幀結果,對比圖中內容,可以看出GIF圖片分解的結果是正確的。 
iOS的GIF動畫效果怎么實現

序列圖像合成GIF圖像

1 GIF圖片合成思路

  多幀圖像合成GIF的過程和GIF分解多幀圖像的過程互逆,GIF圖片分解過程倒過來推,就是GIF圖像合成的過程。這里將上面分解的67張序列單幀圖像作為需要處理的輸入源進行講述。 
  從功能上來說,GIF圖片的合成分為以下三個主要部分。 
(1)加載待處理的67張原始數據源。 
(2)在Document目錄下構建GIF文件。 
(3)設置GIF文件屬性,利用ImageIO編碼GIF文件。

2 GIF圖片合成代碼實現

  如下代碼是根據GIF構建的三個主要步驟進行編寫的。第一部分代碼的功能是將67張PNG圖片讀取到NSMutableArray數組中。代碼第1行初始化可變數組,第2行遍歷67張本地圖片,第3行按照圖片的命名規律,構建67張圖片名稱,第4行加載本地圖片。最后一行將讀取的圖片依次加載到images可變數組中。

 // Part1:讀取67張png圖片 1 let images:NSMutableArray = NSMutableArray() 2 for i in 0...66{// 遍歷本地67張圖片 3 let imagePath = "\(i).png" // 構建圖片名稱 4 let image:UIImage = UIImage(named: imagePath)!// 5 images.addObject(image)// 將圖片添加到數組中}

  代碼第二部分的功能是構建在Document目錄下的GIF文件路徑。具體實現如下所示。

 // Part2:在Document目錄創建gif文件 1 var docs=NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 2 let documentsDirectory = docs[0] as String 3 let gifPath = documentsDirectory+"/plane.gif" 4 print("\(gifPath)") 5 let url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, gifPath as CFString!,CFURLPathStyle.cfurlposixPathStyle, false) 6 let destion = CGImageDestinationCreateWithURL(url!, kUTTypeGIF, images.count, nil)

  代碼1一行和第2行獲取Document路徑地址,第3行代碼通過字符串拼接時組成完整的Document路徑下plane.gif文件路徑。為了方便查看GIF文件所在路徑,第4行代碼將GIF文件路徑打印出來。第5行代碼將plane.gif文件路徑由string類型轉換為URL類型。最后一行代碼是ImageIO中構建GIF圖片非常重要的方法,我們重點來分析該方法的作用和功能。

public func CGImageDestinationCreateWithURL(_ url: CFURL, _ type: CFString, _ count: Int, _ options: CFDictionary?) -> CGImageDestination?

CGImageDestinationCreateWithURL方法的作用是創建一個圖片的目標對象,為了便于大家理解,這里把圖片目標對象比喻為一個集合體。 
iOS的GIF動畫效果怎么實現
                      CGImageDestination結構 
  集合體中描述了構成當前圖片目標對象的一系列參數,如圖片的URL地址、圖片類型、圖片幀數、配置參數等。本代碼中將plane.gif的本地文件路徑作為參數1傳遞給這個圖片目標對象,參數2描述了圖片的類型為GIF圖片,參數3表明當前GIF圖片構成的幀數,參數4暫時給它一個空值。 
  到目前為止,待處理圖片源已經加載到代碼中,GIF圖片Destination也已經完成構建,下面就需要使用ImageIO框架把多幀PNG圖片編碼到GIF圖片中,其處理流程如下。 
iOS的GIF動畫效果怎么實現
  具體實現代碼如下:

 // Part3:設置gif圖片屬性,利用67張png圖片構建gif 1 let cgimagePropertiesDic = [kCGImagePropertyGIFDelayTime as String:0.1]//設置每幀之間播放時間 2 let cgimagePropertiesDestDic =[kCGImagePropertyGIFDictionary as String:cgimagePropertiesDic]; 3 for cgimage in images{ 4 CGImageDestinationAddImage(destion!, (cgimage as AnyObject).cgImage!!,cgimagePropertiesDestDic as CFDictionary?);}// 依次為gif圖像對象添加每一幀元素 5 let gifPropertiesDic:NSMutableDictionary =NSMutableDictionary() 6 gifPropertiesDic.setValue(kCGImagePropertyColorModelRGB,forKey: kCGImagePropertyColorModel as String) 7 gifPropertiesDic.setValue(16, forKey:kCGImagePropertyDepth as String)// 設置圖像的顏色深度 8 gifPropertiesDic.setValue(1, forKey:kCGImagePropertyGIFLoopCount as String)// 設置Gif執行次數 9 let gifDictionaryDestDic = [kCGImagePropertyGIFDictionary as String:gifPropertiesDic] 10 CGImageDestinationSetProperties(destion!,gifDictionaryDestDic as CFDictionary?);//為gif圖像設置屬性 11 CGImageDestinationFinalize(destion!);

  代碼第1行設置GIF圖片屬性,設置當前GIF中每幀圖片展示時間間隔為0.1s。代碼第2行構建一個GIF圖片屬性字典,字典使用GIF每幀之間的時間間隔初始化。代碼第4行使用遍歷的方法將已經準備好的圖片快速追加到GIF圖片的Destination中。代碼第5行初始化一個可變字典對象,該字典對象主要用于設置GIF圖片中每幀圖片屬性。第6行設置圖片彩色空間格式為RGB(Red Green Blue三基色)類型。第7行設置圖片顏色深度。一般來說黑白圖像也稱為二值圖像,顏色深度為1,表示2的一次方,即兩種顏色:黑和白。灰度圖像一般顏色深度為8,表示2的8次方,共計256種顏色,即從黑色到白色的漸變過程有256種。對于彩色圖片來說一般有16位深度和32位深度之說,這里設置為16位深度彩色圖片。代碼第8行設置GIF圖片執行的次數,這里設置為執行一次。代碼第9行和第10行負責將以上圖片設置的各種屬性添加到GIF的Destination目標中。最后一行完成GIF的Destination目標文件構建。 
  可以打印出當前GIF圖片的路徑,在該路徑下可以看到最終生成的GIF圖片。 
iOS的GIF動畫效果怎么實現

Gif圖像展示

  iOS原生并不支持直接顯示GIF圖片,由前面的分析可知,GIF圖片由一幀幀的單幀圖片構成,所以只要實現GIF圖片的分解,接下來就是多組圖片顯示的問題了。為大家介紹另外一種圖片展現形式,即基于UIImageView展現GIF多幀圖片。 
經過對GIF圖片展示思路的分析可以知道,在iOS下展現GIF分為兩步:第一步分解GIF圖片為單幀圖片,第二步在iOS下展現多幀圖片。UIImageView是一個用來展現圖片的UI組件,不過它還有一些動畫屬性可以用來進行逐幀動畫展現。 
考慮到第一步GIF圖片已經分解,所以這里把分解之后的67張圖片先加載進來。 
iOS的GIF動畫效果怎么實現
  UIImageView多幀圖像展示具體實現代碼如下。

1 var images:[UIImage] = [] 2 for i in 0...66{// 遍歷本地67張圖片 3 let imagePath = "\(i).png" // 構建圖片名稱 4 let image:UIImage = UIImage(named: imagePath)! 5 images.append(image)// 將圖片添加到數組中
        } 6 let imageView = UIImageView() 7 imageView.frame = self.view.bounds 8 imageView.contentMode = UIViewContentMode.Center 9 self.view.addSubview(imageView) 10 imageView.animationImages = images 11 imageView.animationDuration = 5 12 imageView.animationRepeatCount = 1 13 imageView.startAnimating()

  代碼第1行初始化一個子元素為UIImage類型的數組對象。第2行到第5行通過for循環將67張圖片依次加載到當前數組中。第6行實例化一個UIImageView實例對象。第7行和第8行設置UIImageView實例對象的frame位置屬性以及圖片的拉伸方式,這里設置為居中顯示。第9行將UIImageView添加到self.view圖層上。第10行將初始化加載的67張圖片添加到UIImageView實例的animationImages上,相當于設置UIImageView的內容。第11行設置UIImageView圖片動畫播放周期。第12行設置動畫重復次數。最后一行啟動UIImageView多幀圖片展示動畫。 
iOS的GIF動畫效果怎么實現

以上就是iOS的GIF動畫效果怎么實現,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万全县| 新余市| 瓦房店市| 鸡西市| 蕉岭县| 中江县| 育儿| 古蔺县| 天水市| 永济市| 古交市| 措美县| 日照市| 天水市| 霍山县| 来凤县| 木里| 读书| 南皮县| 无极县| 曲周县| 平乡县| 河西区| 抚松县| 长汀县| 汝州市| 上高县| 陆丰市| 兴国县| 淮安市| 灌云县| 清水河县| 佛学| 神农架林区| 镇赉县| 汨罗市| 武乡县| 龙口市| 鄯善县| 滨海县| 富宁县|