近来公司工作少,自己就想着做点什么。想起有次在GitHub上想在README上传点GIF图,然后在App Store找制作GIF的APP,但都不是很好用。何不自己做一个?
做出来后界面大概就是这样:(有点丑,以后有时间慢慢再弄哈)
代码
--视频转GIF
核心思想:在目标视频中取出N张图片,然后将图片合成GIF。
第一步 :取出N张图片
这里需要用到AVURLAsset 和 AVAssetImageGenerator。
self.asset = AVURLAsset(url: sourceFileURL, options: nil)
let generator = AVAssetImageGenerator(asset: asset)
generator.generateCGImagesAsynchronously(forTimes: times, completionHandler: { (requestedTime, image, actualTime, result, error) in
//image 即为取出来的图片
})
generateCGImagesAsynchronously方法的第一个参数是一个包含NSValue类型的数组,数组里每一个对象都是CMTime结构体,表示你想要生成的图片在视频中的时间点。
var timePoints: [TimePoint] = []
for frameNumber in 0 ..< frameCount {
let seconds: Float64 = Float64(startTime) + (Float64(increment) * Float64(frameNumber))
let time = CMTimeMakeWithSeconds(seconds, preferredTimescale: Constants.TimeInterval)
timePoints.append(time)
}
frameCount即为你想要取多少张图片来制作GIF(我的思路是每秒取10张不同的)。
第二步 :制作图片
CGImageDestinationRef 负责对图片的写操作
guard let destination = CGImageDestinationCreateWithURL(fileURL! as CFURL, kUTTypeGIF, frameCount, nil) else {
throw GIFMakerError.DestinationNotFound
}
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary)
CGImageDestinationAddImage(destination, imageRef, frameProperties as CFDictionary)
// Finalize the gif
if !CGImageDestinationFinalize(destination) {
throw GIFMakerError.DestinationFinalize
}
//返回的 fileURL就是GIF路径
return fileURL!
--图片转GIF
跟上面的视频转GIF是一样的,少了取图片的步骤而已。
let docs = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let gifPath = docs[0] as String + "/refresh.gif"
let url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, gifPath as CFString, .cfurlposixPathStyle, false)
let destion = CGImageDestinationCreateWithURL(url!, kUTTypeGIF, images.count, nil)
// 设置gif图片属性
// 设置每帧之间播放的时间0.1
let delayTime = [kCGImagePropertyGIFDelayTime as String:0.1]
let destDic = [kCGImagePropertyGIFDictionary as String:delayTime]
// 依次为gif图像对象添加每一帧属性 ,images就是需要合成的图片数组
for image in images {
CGImageDestinationAddImage(destion!, image.cgImage!, destDic as CFDictionary?)
}
如果有帮助到你的话,帮忙点个star,谢谢!
demo地址