我有一个生成带有UIImages数组的gif的函数。图像阵列的大小为31,但是我将容量设置为15,因为我仅使用选择图像。
最终,我遇到的问题是,当我使用函数调整CGImage的大小并将其用作CGImageDestinationAddImage中的图像时,生成的gif就是我之前发送的照片,而不是我通过这次起作用。我不知道这是怎么发生的,因为即使关闭了应用程序,生成的gif仍然可以生成我之前使用过的图像数组。
下面是基本的generateGIF和imageWithImage函数,然后我将展示尝试过获得结果的不同方法。
func generateGIF(photos: [UIImage], filename: String) -> Bool {
let documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = documentsDirectoryPath.appending(filename)
let fileProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]]
var gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFDelayTime as String: 0.1]] // actual speed is 0.2
gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImageDestinationLossyCompressionQuality as String: 0.1]]
let cfURL = URL(fileURLWithPath: path) as CFURL
let imageCapacity = 15
if let destination = CGImageDestinationCreateWithURL(cfURL, kUTTypeGIF, imageCapacity, nil) {
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary?)
var inc:Int = 0
for _ in 0..<imageCapacity { // actual photos.count is 31
// I create 'photo' to determine what new size I should
// use, for my own convenience, not included in this code
let photo = photos[inc]
let width:CGFloat = 200
let smallerPhoto = imageWithImage(image:photos[inc], newWidth:width)
CGImageDestinationAddImage(destination, smallerPhoto.cgImage!, gifProperties as CFDictionary?)
inc += 2
}
}
// do something with gif, i.e. save to photo albums or display
// in my case I save using path as a URL
}
func imageWithImage(image:UIImage, newWidth:CGFloat) -> UIImage{
let scale = newWidth / image.size.width
let newHeight = image.size.height * scale
let newSize = CGSize(width: newWidth, height: newHeight)
let renderer = UIGraphicsImageRenderer(size: newSize)
let image = renderer.image { (context) in
image.draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: newSize))
}
return image
}
正如我所解释的,使用上面的代码生成的gif将使用我之前捕获的图像制作gif。
如果我在CGImageDestinationAddImage中使用“照片”,则生成的gif是我所期望的,而不是我上次创建的gif,但是CGImage不会调整大小,因为我没有通过该函数传递它们。
CGImageDestinationAddImage(destination, photo.cgImage!, gifProperties as CFDictionary?)
作为实验,我将smallPhoto定义为“照片”,希望它可以复制之前定义的内容,并将其与CGImageDestinationAddImage一起使用。取而代之的是,生成的gif是我从上次发送到函数generateGIF函数的UIImages数组中得到的。
let smallerPhoto = photo
CGImageDestinationAddImage(destination, smallerPhoto.cgImage!, gifProperties as CFDictionary?)
另外,我尝试直接将smallerPhoto定义为照片中的当前数组索引,并在CGImageDestinationAddImage中使用它。这给了我传递给generateGIF的正确图像集。但是,这跳过了调整CGImages的大小,这是我需要做的。
let smallerPhoto = photos[inc]
CGImageDestinationAddImage(destination, smallerPhoto.cgImage!, gifProperties as CFDictionary?)
最佳答案
我需要使用CGImageDestinationFinalize(destination)最终确定图像。
func generateGIF(照片:[UIImage],文件名:String)->布尔{
let documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = documentsDirectoryPath.appending(filename)
let fileProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]]
var gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFDelayTime as String: 0.1]] // actual speed is 0.2
gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImageDestinationLossyCompressionQuality as String: 0.1]]
let cfURL = URL(fileURLWithPath: path) as CFURL
let imageCapacity = 15
if let destination = CGImageDestinationCreateWithURL(cfURL, kUTTypeGIF, imageCapacity, nil) {
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary?)
var inc:Int = 0
for _ in 0..<imageCapacity { // actual photos.count is 31
// I create 'photo' to determine what new size I should
// use, for my own convenience, not included in this code
let photo = photos[inc]
let width:CGFloat = 200
let smallerPhoto = imageWithImage(image:photos[inc], newWidth:width)
CGImageDestinationAddImage(destination, smallerPhoto.cgImage!, gifProperties as CFDictionary?)
inc += 2
}
}
let finalized:Bool = CGImageDestinationFinalize(destination)
if finalized {
// do something with gif, i.e. save to photo albums or display
// in my case I save using path as a URL
}
// return finalized boolean value
return finalized
}