Swift Animation GIF 动画

Posted by Calvin on 2017-06-23

GIF 分解为单帧图片

5个模块,4个过程

  1. 本地读取GIF图片,将其转换为 NSData 数据类型
  2. 将 NSData 作为 ImageIO 模块的输入
  3. 获取 ImageIO 的输出数据:UIImage
  4. 将获取到的 UIImage 数据存储为 JPG 或者 PNG 格式保存到本地
// 读取 GIF 文件并将其转换为 NSData 类型
let gifPath:NSString = Bundle.main.path(forResource: "plane", ofType: "gif")! as NSString
let gifData:Data = try!Data(contentsOf: URL(fileURLWithPath: (gifPath as NSString) as String))
// 将 NSData 转换为 ImageIO 可以直接处理的数据类型 CGImageSource
let gifDataSource:CGImageSource = CGImageSourceCreateWithData(gifData as CFData, nil)!
// 获取 GIF 的分帧个数
let gifImageCount:Int = CGImageSourceGetCount(gifDataSource)
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 )
let imageData:Data = UIImagePNGRepresentation(image)!
var docs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = docs[0] as String
let imagePath = documentsDirectory+"/\(i)"+".png"
try? imageData .write(to: URL(fileURLWithPath: imagePath), options: [.atomic])
print("\(imagePath)")
}

分解后的图像:

20170624149830402534492.png

序列图像合成 GIF 图像

  1. 加载待处理的67张原始数据源
  2. 在 Document 目录下构建 GIF 文件
  3. 设置 GiF 文件属性,利用 ImageIO 编码 GIF 文件
// part1:读取 67 张 PNG 图片并添加到数组
let images:NSMutableArray = NSMutableArray()
for i in 0...66 {
let imagePath = "\(i).png"
let image:UIImage = UIImage(named: imagePath)!
images.add(image)
}
// part2:在 Document 目录创建 GIF 文件
var docs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = docs[0] as String
let gifPath = documentsDirectory+"/plane.gif"
print("\(gifPath)")
let url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, gifPath as CFString!, CFURLPathStyle.cfurlposixPathStyle, false)
let destion = CGImageDestinationCreateWithURL(url!, kUTTypeGIF, images.count, nil)
// part3:设置 gif 图片属性,利用67张 png 图片构建 gif
let cgimagePropertiesDic = [kCGImagePropertyGIFDelayTime as String:0.1] // 设置每帧之间播放时间
let cgimagePropertiesDestDic = [kCGImagePropertyGIFDictionary as String:cgimagePropertiesDic];
for cgimage in images{
CGImageDestinationAddImage(destion!, (cgimage as AnyObject).cgImage!!,cgimagePropertiesDestDic as CFDictionary?);
} // 依次为 gif 图像对象添加每一帧元素
let gifPropertiesDic:NSMutableDictionary = NSMutableDictionary()
gifPropertiesDic.setValue(kCGImagePropertyColorModelRGB, forKey: kCGImagePropertyColorModel as String) // 设置图像的彩色空间格式
gifPropertiesDic.setValue(16, forKey: kCGImagePropertyDepth as String) // 设置图像的颜色深度
gifPropertiesDic.setValue(1, forKey: kCGImagePropertyGIFLoopCount as String) // 设置Gif执行次数
let gifDictionaryDestDic = [kCGImagePropertyGIFDictionary as String:gifPropertiesDic]
CGImageDestinationSetProperties(destion!,gifDictionaryDestDic as CFDictionary?) //为gif图像设置属性

GIF 图像展示

var images:[UIImage] = []
for i in 0...66{// 遍历本地67张图片
let imagePath = "\(i).png" // 构建图片名称
let image:UIImage = UIImage(named: imagePath)!//构建UIImage
images.append(image)// 将图片添加到数组中
}
let imageView = UIImageView()
imageView.frame = self.view.bounds
imageView.contentMode = UIViewContentMode.center
self.view.addSubview(imageView)
imageView.animationImages = images
imageView.animationDuration = 5 // 动画播放时长
imageView.animationRepeatCount = 1 // 动画重复次数
imageView.startAnimating()