Skip to content

Commit

Permalink
using asynchronous image decoding to reduce the main thread CPU usage
Browse files Browse the repository at this point in the history
  • Loading branch information
wangjwchn committed Apr 24, 2016
1 parent 8e5df12 commit 8fec419
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 14 deletions.
50 changes: 36 additions & 14 deletions JWAnimatedImage/JWAnimatedImageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ let _haveCacheKey = malloc(4)
let _loopTimeKey = malloc(4)
let _displayingKey = malloc(4)
let _animationManagerKey = malloc(4)
let _sameFrameCheckKey = malloc(4)

public extension UIImageView{

Expand All @@ -42,13 +43,13 @@ public extension UIImageView{
self.syncFactor = 0
self.displayOrderIndex = 0
self.cache = NSCache()
self.sameFrameCheck = false
self.haveCache = false
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,0,nil)!)

self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,0,[(kCGImageSourceShouldCacheImmediately as String): true])!)
if !manager.SearchImageView(self){
manager.AddImageView(self)
StartDisplay()
}
StartDisplay()
}

public func StartDisplay(){
Expand All @@ -71,17 +72,11 @@ public extension UIImageView{
self.haveCache = false
}
}

public func updateCurrentImage(){
if(self.displaying == true){
if(self.haveCache==false){
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![self.displayOrderIndex],nil)!)
}else{
if let image = (cache.objectForKey(self.displayOrderIndex) as? UIImage){
self.currentImage = image
}else{
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![self.displayOrderIndex],nil)!)
}//prevent case that cache is not ready
if(self.sameFrameCheck == false){
updateFrame()
}
updateIndex()
if(loopTime == 0 || isDisplayedInScreen(self)==false){
Expand Down Expand Up @@ -123,17 +118,35 @@ public extension UIImageView{
private func updateIndex(){
self.syncFactor = (self.syncFactor+1)%gifImage.displayRefreshFactor!
if(self.syncFactor==0){
self.displayOrderIndex = (self.displayOrderIndex+1)%self.gifImage.imageCount!
let displayOrderIndexNext = (self.displayOrderIndex+1)%self.gifImage.imageCount!
if(self.gifImage.displayOrder![displayOrderIndexNext] == self.gifImage.displayOrder![self.displayOrderIndex]){
self.sameFrameCheck = true
}else{
self.sameFrameCheck = false
}
self.displayOrderIndex = displayOrderIndexNext
if(displayOrderIndex==0){
self.loopTime -= 1;
}
}
}

public func updateFrame(){
if(self.haveCache==false){
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![self.displayOrderIndex],[(kCGImageSourceShouldCacheImmediately as String): true])!)
}else{
if let image = (cache.objectForKey(self.displayOrderIndex) as? UIImage){
self.currentImage = image
}else{
self.currentImage = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![self.displayOrderIndex],[(kCGImageSourceShouldCache as String): false])!)
}//prevent case that cache is not ready
}
}

private func prepareCache(){
self.cache.removeAllObjects()
for i in 0..<self.gifImage.displayOrder!.count {
let image = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![i],nil)!)
let image = UIImage(CGImage: CGImageSourceCreateImageAtIndex(self.gifImage.imageSource!,self.gifImage.displayOrder![self.displayOrderIndex],[(kCGImageSourceShouldCacheImmediately as String): true])!)
self.cache.setObject(image,forKey:i)
}
}
Expand Down Expand Up @@ -199,6 +212,15 @@ public extension UIImageView{
objc_setAssociatedObject(self, _haveCacheKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN);
}
}

private var sameFrameCheck:Bool{
get {
return (objc_getAssociatedObject(self, _sameFrameCheckKey) as! Bool)
}
set {
objc_setAssociatedObject(self, _sameFrameCheckKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN);
}
}

public var displaying:Bool{
get {
Expand Down
1 change: 1 addition & 0 deletions JWAnimatedImage/JWAnimationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class JWAnimationManager{
private var memoryLimit:Int
public var haveCache:Bool


public init(memoryLimit:Int){
self.memoryLimit = memoryLimit
self.totalGifSize = 0
Expand Down

0 comments on commit 8fec419

Please sign in to comment.