forked from frosty/Flipbook
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathFlipbook.swift
98 lines (76 loc) · 3.13 KB
/
Flipbook.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//
// Flipbook.swift
// Flipbook
//
// Created by James Frost on 21/11/2014.
// Copyright (c) 2014 James Frost. All rights reserved.
//
import Foundation
import UIKit
class Flipbook: NSObject {
private lazy var displayLink: CADisplayLink = CADisplayLink(target: self, selector: "displayLinkTick:")
// The view to capture
private var targetView: UIView?
private var duration: NSTimeInterval?
private var startTime: CFTimeInterval?
private var imagePrefix: String!
private var imageCounter = 0
// Render the target view to images for the specified duration
func renderTargetView(view: UIView, duration: NSTimeInterval, imagePrefix: String, frameInterval: Int = 1) {
assert(frameInterval >= 1)
self.targetView = view
self.duration = duration
self.imagePrefix = imagePrefix
imageCounter = 0
displayLink.frameInterval = frameInterval
displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
println("[Flipbook] Starting capture...")
}
func renderTargetView(view: UIView, imagePrefix: String, frameCount: Int, updateBlock: (view: UIView, frame: Int) -> Void) {
self.imagePrefix = imagePrefix
for frame in 0..<frameCount {
updateBlock(view: view, frame: frame)
renderViewToImage(view)
}
}
func displayLinkTick(sender: CADisplayLink) {
if startTime == nil {
startTime = sender.timestamp
}
renderViewToImage(self.targetView)
if sender.timestamp - startTime! > duration {
sender.invalidate()
sender.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
println("[Flipbook] Images exported to: \(documentsDirectory()!)")
println("[Flipbook] Capture complete!")
}
}
private func newImagePath() -> String? {
if let documentsDirectory = documentsDirectory() {
let imagePath = documentsDirectory.stringByAppendingPathComponent(NSString(format: "%@-%[email protected]", imagePrefix, imageCounter++))
return imagePath
}
return nil
}
private func renderViewToImage(view: UIView?) {
if let snapshot = view?.snapshotImage() {
if let imagePath = self.newImagePath() {
UIImagePNGRepresentation(snapshot).writeToFile(imagePath, atomically: true)
}
}
}
private func documentsDirectory() -> String? {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
return paths.last as? String
}
}
extension UIView {
func snapshotImage() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, opaque, 2.0)
let layer: CALayer = self.layer.presentationLayer() as? CALayer ?? self.layer
layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}