在 Swift 中压缩 GIF 的方法?
Ways to compress GIFs in Swift?
我的 gif 生成器功能降低了分辨率并最小化了一系列照片的帧,但我没有任何东西可以减少颜色的数量或使其有损。我将如何在 Swift 4 中执行此操作?
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]]
let gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFDelayTime as String: 0.1]] // actual speed is 0.2
let cfURL = URL(fileURLWithPath: path) as CFURL
if let destination = CGImageDestinationCreateWithURL(cfURL, kUTTypeGIF, photos.count, nil) {
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary?)
var inc:Int = 0
for _ in 0..<15 { // actual photos.count is 31
let photo = photos[inc]
var width:CGFloat = photo.size.width
var height:CGFloat = photo.size.height
let maxWidthHeight:CGFloat = 500
if(photo.size.width > maxWidthHeight || photo.size.height > maxWidthHeight){ // gif beyond max width or height
if(photo.size.width > photo.size.height){
width = maxWidthHeight
let percentChange = width / photo.size.width
height = photo.size.height * percentChange
}else{
height = maxWidthHeight
let percentChange = height / photo.size.height
width = photo.size.width * percentChange
}
print("w:\(width) h:\(height) inc:\(inc)")
}
let smallerPhoto = imageWithImage(image:photo, scaledToSize:CGSize(width:width, height:height))
CGImageDestinationAddImage(destination, smallerPhoto.cgImage!, gifProperties as CFDictionary?)
inc+=2 // skipping ahead incrementation for less frames
}
// here it's saving to a photo album when it's done and reporting the filesize
CustomPhotoAlbum.sharedInstance.savePhoto(URL: URL(fileURLWithPath: path), completion: {
var fileSize : UInt64
do {
let attr = try FileManager.default.attributesOfItem(atPath: path)
fileSize = attr[FileAttributeKey.size] as! UInt64
print("gif is \(fileSize/1000000) megabytes")
} catch {
print("Error: \(error)")
}
})
return CGImageDestinationFinalize(destination)
}
return false
}
任何超过 500 宽度或高度的文件 returns 一个大约 11 兆字节的文件。我想它可能会小得多。
根据 gifsicle
github 查看 giflossy
。它完全可以满足您的需求,甚至更多。它在 C 中,但您可以从那里获得一些灵感并将相关部分移植到 swift。
我的 gif 生成器功能降低了分辨率并最小化了一系列照片的帧,但我没有任何东西可以减少颜色的数量或使其有损。我将如何在 Swift 4 中执行此操作?
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]]
let gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFDelayTime as String: 0.1]] // actual speed is 0.2
let cfURL = URL(fileURLWithPath: path) as CFURL
if let destination = CGImageDestinationCreateWithURL(cfURL, kUTTypeGIF, photos.count, nil) {
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary?)
var inc:Int = 0
for _ in 0..<15 { // actual photos.count is 31
let photo = photos[inc]
var width:CGFloat = photo.size.width
var height:CGFloat = photo.size.height
let maxWidthHeight:CGFloat = 500
if(photo.size.width > maxWidthHeight || photo.size.height > maxWidthHeight){ // gif beyond max width or height
if(photo.size.width > photo.size.height){
width = maxWidthHeight
let percentChange = width / photo.size.width
height = photo.size.height * percentChange
}else{
height = maxWidthHeight
let percentChange = height / photo.size.height
width = photo.size.width * percentChange
}
print("w:\(width) h:\(height) inc:\(inc)")
}
let smallerPhoto = imageWithImage(image:photo, scaledToSize:CGSize(width:width, height:height))
CGImageDestinationAddImage(destination, smallerPhoto.cgImage!, gifProperties as CFDictionary?)
inc+=2 // skipping ahead incrementation for less frames
}
// here it's saving to a photo album when it's done and reporting the filesize
CustomPhotoAlbum.sharedInstance.savePhoto(URL: URL(fileURLWithPath: path), completion: {
var fileSize : UInt64
do {
let attr = try FileManager.default.attributesOfItem(atPath: path)
fileSize = attr[FileAttributeKey.size] as! UInt64
print("gif is \(fileSize/1000000) megabytes")
} catch {
print("Error: \(error)")
}
})
return CGImageDestinationFinalize(destination)
}
return false
}
任何超过 500 宽度或高度的文件 returns 一个大约 11 兆字节的文件。我想它可能会小得多。
根据 gifsicle
github 查看 giflossy
。它完全可以满足您的需求,甚至更多。它在 C 中,但您可以从那里获得一些灵感并将相关部分移植到 swift。