如何解决从 UIImagePickerController 加载 GIF
我正在使用帮助文件来让我在 Xcode 中显示 GIF。这是帮助文件:
import UIKit
import ImageIO
extension UIImageView {
public func loadGif(name: String) {
dispatchQueue.global().async {
let image = UIImage.gif(name: name)
dispatchQueue.main.async {
self.image = image
}
}
}
@available(iOS 9.0,*)
public func loadGif(asset: String) {
dispatchQueue.global().async {
let image = UIImage.gif(asset: asset)
dispatchQueue.main.async {
self.image = image
}
}
}
}
extension UIImage {
public class func gif(data: Data) -> UIImage? {
// Create source from data
guard let source = CGImageSourceCreateWithData(data as CFData,nil) else {
print("SwiftGif: Source for the image does not exist")
return nil
}
return UIImage.animatedImageWithSource(source)
}
public class func gif(url: String) -> UIImage? {
// Validate URL
guard let bundleURL = URL(string: url) else {
print("SwiftGif: This image named \"\(url)\" does not exist")
return nil
}
// Validate data
guard let imageData = try? Data(contentsOf: bundleURL) else {
print("SwiftGif: Cannot turn image named \"\(url)\" into NSData")
return nil
}
return gif(data: imageData)
}
public class func gif(name: String) -> UIImage? {
// Check for existance of gif
guard let bundleURL = Bundle.main
.url(forResource: name,withExtension: "gif") else {
print("SwiftGif: This image named \"\(name)\" does not exist")
return nil
}
// Validate data
guard let imageData = try? Data(contentsOf: bundleURL) else {
print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")
return nil
}
return gif(data: imageData)
}
@available(iOS 9.0,*)
public class func gif(asset: String) -> UIImage? {
// Create source from assets catalog
guard let dataAsset = NSDataAsset(name: asset) else {
print("SwiftGif: Cannot turn image named \"\(asset)\" into NSDataAsset")
return nil
}
return gif(data: dataAsset.data)
}
internal class func delayForImageAtIndex(_ index: Int,source: CGImageSource!) -> Double {
var delay = 0.1
// Get dictionaries
let cfProperties = CGImageSourcecopyPropertiesAtIndex(source,index,nil)
let gifPropertiesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0)
defer {
gifPropertiesPointer.deallocate()
}
let unsafePointer = Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()
if CFDictionaryGetValueIfPresent(cfProperties,unsafePointer,gifPropertiesPointer) == false {
return delay
}
let gifProperties: CFDictionary = unsafeBitCast(gifPropertiesPointer.pointee,to: CFDictionary.self)
// Get delay time
var delayObject: AnyObject = unsafeBitCast(
CFDictionaryGetValue(gifProperties,Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()),to: AnyObject.self)
if delayObject.doubleValue == 0 {
delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()),to: AnyObject.self)
}
if let delayObject = delayObject as? Double,delayObject > 0 {
delay = delayObject
} else {
delay = 0.1 // Make sure they're not too fast
}
return delay
}
internal class func gcdForPair(_ lhs: Int?,_ rhs: Int?) -> Int {
var lhs = lhs
var rhs = rhs
// Check if one of them is nil
if rhs == nil || lhs == nil {
if rhs != nil {
return rhs!
} else if lhs != nil {
return lhs!
} else {
return 0
}
}
// Swap for modulo
if lhs! < rhs! {
let ctp = lhs
lhs = rhs
rhs = ctp
}
// Get greatest common divisor
var rest: Int
while true {
rest = lhs! % rhs!
if rest == 0 {
return rhs! // Found it
} else {
lhs = rhs
rhs = rest
}
}
}
internal class func gcdForArray(_ array: [Int]) -> Int {
if array.isEmpty {
return 1
}
var gcd = array[0]
for val in array {
gcd = UIImage.gcdForPair(val,gcd)
}
return gcd
}
internal class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? {
let count = CGImageSourceGetCount(source)
var images = [CGImage]()
var delays = [Int]()
// Fill arrays
for index in 0..<count {
// Add image
if let image = CGImageSourceCreateImageAtIndex(source,nil) {
images.append(image)
}
// At it's delay in cs
let delaySeconds = UIImage.delayForImageAtIndex(Int(index),source: source)
delays.append(Int(delaySeconds * 1000.0)) // Seconds to ms
}
// Calculate full duration
let duration: Int = {
var sum = 0
for val: Int in delays {
sum += val
}
return sum
}()
// Get frames
let gcd = gcdForArray(delays)
var frames = [UIImage]()
var frame: UIImage
var frameCount: Int
for index in 0..<count {
frame = UIImage(cgImage: images[Int(index)])
frameCount = Int(delays[Int(index)] / gcd)
for _ in 0..<frameCount {
frames.append(frame)
}
}
// heyhey
let animation = UIImage.animatedImage(with: frames,duration: Double(duration) / 1000.0)
return animation
}
}
我还希望能够从相机加载 GIF 并显示它们。当我尝试以下操作时,它显示的是静止图像,而不是 GIF。
@objc func buttonForImageSelectionDuringGoalCreationTapped(sender: UIButton!) {
print("Taylor Swift Wants A New Image")
let myImagePickerController = UIImagePickerController()
myImagePickerController.delegate = self
myImagePickerController.sourceType = .photoLibrary
self.present(myImagePickerController,animated: true,completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediawithInfo info: [UIImagePickerController.InfoKey : Any]) {
let selectedImage = info[UIImagePickerController.InfoKey.originalImage]
self.imageOfCurrentSuccessImageForGoalCreation.image = selectedImage as? UIImage
picker.dismiss(animated: true,completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true,completion: nil)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。