Skip to content
This repository has been archived by the owner on Jan 14, 2021. It is now read-only.

Made calling SwiftGif Easier #14

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ A small `UIImage` extension with gif support.
Import the `Gif.swift` in your project and do the following:
```swift
// jeremy.gif
var url = NSBundle.mainBundle().URLForResource("jeremy", withExtension: "gif")
var imageData = NSData(contentsOfURL: url)

// Returns an animated UIImage
UIImage.animatedImageWithData(imageData)
let jeremyGif = UIImage.gifWithName("jeremy")
// Use the UIImage in your UIImageView
let imageView = UIImageView(image: jeremyGif)
```

## How does it work?
Expand Down
78 changes: 45 additions & 33 deletions SwiftGifCommon/UIImage+Gif.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,30 @@ import UIKit
import ImageIO

extension UIImage {

public class func animatedImageWithData(data: NSData) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data, nil) else { return nil }


public class func gifWithData(data: NSData) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data, nil) else {
print("SwiftGif: Source for the image does not exist")
return nil
}
return UIImage.animatedImageWithSource(source)
}

class func delayForImageAtIndex(index: Int, source: CGImageSource!)
-> Double {

public class func gifWithName(name: String) -> UIImage? {
guard let bundleURL = NSBundle.mainBundle().URLForResource(name, withExtension: "gif") else {
print("SwiftGif: This image named \"\(name)\" does not exist")
return nil
}
guard let imageData = NSData(contentsOfURL: bundleURL) else {
print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")
return nil
}
return gifWithData(imageData)
}

class func delayForImageAtIndex(index: Int, source: CGImageSource!) -> Double {
var delay = 0.1

// Get dictionaries
let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
let gifProperties: CFDictionaryRef = unsafeBitCast(
Expand All @@ -37,17 +50,16 @@ extension UIImage {
delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
unsafeAddressOf(kCGImagePropertyGIFDelayTime)), AnyObject.self)
}

delay = delayObject as! Double

if delay < 0.1 {
delay = 0.1 // Make sure they're not too fast
}



return delay
}

class func gcdForPair(var a: Int?, var _ b: Int?) -> Int {
// Check if one of them is nil
if b == nil || a == nil {
Expand All @@ -59,19 +71,19 @@ extension UIImage {
return 0
}
}

// Swap for modulo
if a < b {
let c = a
a = b
b = c
}

// Get greatest common divisor
var rest: Int
while true {
rest = a! % b!

if rest == 0 {
return b! // Found it
} else {
Expand All @@ -80,70 +92,70 @@ extension UIImage {
}
}
}

class func gcdForArray(array: Array<Int>) -> Int {
if array.isEmpty {
return 1
}

var gcd = array[0]

for val in array {
gcd = UIImage.gcdForPair(val, gcd)
}

return gcd
}

public class func animatedImageWithSource(source: CGImageSource) -> UIImage? {
class func animatedImageWithSource(source: CGImageSource) -> UIImage? {
let count = CGImageSourceGetCount(source)
var images = [CGImageRef]()
var delays = [Int]()

// Fill arrays
for i in 0..<count {
// Add image
if let image = CGImageSourceCreateImageAtIndex(source, i, nil) {
images.append(image)
}

// At it's delay in cs
let delaySeconds = UIImage.delayForImageAtIndex(Int(i),
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 i in 0..<count {
frame = UIImage(CGImage: images[Int(i)])
frameCount = Int(delays[Int(i)] / gcd)

for _ in 0..<frameCount {
frames.append(frame)
}
}

// Heyhey
let animation = UIImage.animatedImageWithImages(frames,
duration: Double(duration) / 1000.0)

return animation
}

}
17 changes: 7 additions & 10 deletions SwiftGifDemo/RootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,19 @@ class RootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

var imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("jeremy", withExtension: "gif")!)
let jeremy = UIImage.animatedImageWithData(imageData!)
var imageView = UIImageView(image: jeremy)
let jeremyGif = UIImage.gifWithName("jeremy")
let imageView = UIImageView(image: jeremyGif)
imageView.frame = CGRect(x: 0.0, y: 20.0, width: 350.0, height: 202.0)

view.addSubview(imageView)


imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("adventure-time", withExtension: "gif")!)
let advTime = UIImage.animatedImageWithData(imageData!)
imageView = UIImageView(image: advTime)
imageView.frame = CGRect(x: 0.0, y: 222.0, width: 350.0, height: 202.0)
let imageData = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("adventure-time", withExtension: "gif")!)
let advTimeGif = UIImage.gifWithData(imageData!)
let imageView2 = UIImageView(image: advTimeGif)
imageView2.frame = CGRect(x: 0.0, y: 222.0, width: 350.0, height: 202.0)

view.addSubview(imageView)
view.addSubview(imageView2)
}

override func didReceiveMemoryWarning() {
Expand Down