Skip to content

Instantly share code, notes, and snippets.

@mtrezza
Forked from toddheasley/UIImage.swift
Created November 17, 2017 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtrezza/2638288a1dca0beb921924e4f5a082da to your computer and use it in GitHub Desktop.
Save mtrezza/2638288a1dca0beb921924e4f5a082da to your computer and use it in GitHub Desktop.
Animated GIF support for UIImage
//
// © 2017 @toddheasley
//
import UIKit
extension UIImage {
static func animatedImage(data: Data) -> UIImage? {
guard let source: CGImageSource = CGImageSourceCreateWithData(data as CFData, nil), CGImageSourceGetCount(source) > 1 else {
return UIImage(data: data)
}
// Collect key frames and durations
var frames: [(image: CGImage, delay: TimeInterval)] = []
for i: Int in 0 ..< CGImageSourceGetCount(source) {
guard let image = CGImageSourceCreateImageAtIndex(source, i, nil), let frame = CGImageSourceCopyPropertiesAtIndex(source, i, nil) as? [String: Any], let gif = frame["{GIF}"] as? [String: Any] else {
continue
}
// Mimic WebKit approach to determine frame delay
if let delay = gif["UnclampedDelayTime"] as? TimeInterval, delay > 0.0 {
frames.append((image, delay)) // Prefer "unclamped" delay time
} else if let delay = gif["DelayTime"] as? TimeInterval, delay > 0.0 {
frames.append((image, delay))
} else {
frames.append((image, 0.1)) // WebKit default
}
}
// Convert key frames to animated image
var images: [UIImage] = []
var duration: TimeInterval = 0.0
for frame in frames {
let image = UIImage(cgImage: frame.image)
for _ in 0 ..< Int(frame.delay * 100.0) {
images.append(image) // Add fill frames
}
duration += frame.delay
}
return UIImage.animatedImage(with: images, duration: duration)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment