Rotating an image
orta opened this issue · 2 comments
I expect a lot of people will be interested in this, so I'm putting up my example code. This uses core image to rotate the image inside an imageview and records the rotation into a animation.
This is because I couldn't get a transform to work on my snapshots how I would normally do it:
let number = CGFloat(-1.01 * M_PI)
let rotationTransform = CATransform3DMakeRotation(number, 0, 0, 1)
let rotationAnimation = CABasicAnimation(keyPath: "transform")
rotationAnimation.toValue = NSValue(CATransform3D: rotationTransform);
rotationAnimation.duration = 0.4
rotationAnimation.cumulative = true
rotationAnimation.repeatCount = 10000;
let image = UIImage(named: "Spinner-0");
let imageView = UIImageView(image: image);
imageView.layer.addAnimation(rotationAnimation, forKey:"transform")
let outer = UIView(frame: imageView.bounds)
outer.addSubview(imageView)
view.addSubview(outer)
arcFlipbook = Flipbook()
arcFlipbook.renderTargetView(outer, imagePrefix: "Progress-Spinner", frameCount: 20) { (view, frame) in
return
}
Zip of my working example using CIImage: http://cl.ly/3H20450t1T0F/Flipbook-orta.zip
I have a similar problem there I modify the view's transform
inside the updateBlock
, but because the UI loop is not running no "visible" changes are captured by Flipbook.
I tried using dispatch_async
with no luck:
for frame in 0..<frameCount {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
updateBlock(view: view, frame: frame)
self.renderViewToImage(view)
})
}
I have made some changes in Flipbook class to make this, I'm sure there are better ways to do this but it works ^_^
I added 3 new private properties
private lazy var displayLinkByFrameCount: CADisplayLink = CADisplayLink(target: self, selector: "displayLinkTickByFrameCount:")
private var frameCount = 0
private var updateBlock: ((view: UIView, frame: Int) -> Void)?
I have modified the method func renderTargetView(view: UIView, imagePrefix: String, frameCount: Int, updateBlock: (view: UIView, frame: Int) -> Void)
func renderTargetView(view: UIView, imagePrefix: String, frameCount: Int, updateBlock: (view: UIView, frame: Int) -> Void) {
self.targetView = view
self.imagePrefix = imagePrefix
self.frameCount = frameCount
self.updateBlock = updateBlock
self.imageCounter = 0
displayLinkByFrameCount.frameInterval = 1
displayLinkByFrameCount.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
print("[Flipbook] Starting capture...")
}
And I added this new method
func displayLinkTickByFrameCount(sender: CADisplayLink) {
renderViewToImage(self.targetView)
if self.imageCounter > self.frameCount {
sender.invalidate()
sender.removeFromRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
print("[Flipbook] Images exported to: \(documentsDirectory()!)")
print("[Flipbook] Capture complete!")
} else {
self.updateBlock!(view: self.targetView!, frame: self.imageCounter)
}
}