From 4335fb7e41c5c85c75939920a9723185387ea11a Mon Sep 17 00:00:00 2001 From: Vincent Pizzo Date: Fri, 6 Dec 2013 16:51:31 -0600 Subject: [PATCH] Using webkit's method for determing frame durations of various gif images --- SDWebImage/UIImage+GIF.m | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/SDWebImage/UIImage+GIF.m b/SDWebImage/UIImage+GIF.m index d19fa41..1aa8bf0 100755 --- a/SDWebImage/UIImage+GIF.m +++ b/SDWebImage/UIImage+GIF.m @@ -38,8 +38,7 @@ { CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); - NSDictionary *frameProperties = CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source, i, NULL)); - duration += [[[frameProperties objectForKey:(NSString*)kCGImagePropertyGIFDictionary] objectForKey:(NSString*)kCGImagePropertyGIFDelayTime] doubleValue]; + duration += [self frameDurationAtIndex:i source:source]; [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; @@ -59,6 +58,36 @@ return animatedImage; } ++ (float)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source +{ + float frameDuration = 0.1f; + CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source,index,nil); + NSDictionary *frameProperties = (__bridge NSDictionary*)cfFrameProperties; + NSDictionary *gifProperties = frameProperties[(NSString*)kCGImagePropertyGIFDictionary]; + + NSNumber *delayTimeUnclampedProp = gifProperties[(NSString*)kCGImagePropertyGIFUnclampedDelayTime]; + if(delayTimeUnclampedProp) { + frameDuration = [delayTimeUnclampedProp floatValue]; + } else { + + NSNumber *delayTimeProp = gifProperties[(NSString*)kCGImagePropertyGIFDelayTime]; + if(delayTimeProp) { + frameDuration = [delayTimeProp floatValue]; + } + } + + // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. + // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify + // a duration of <= 10 ms. See and + // for more information. + + if (frameDuration < 0.011f) + frameDuration = 0.100f; + + CFRelease(cfFrameProperties); + return frameDuration; +} + + (UIImage *)sd_animatedGIFNamed:(NSString *)name { CGFloat scale = [UIScreen mainScreen].scale; @@ -108,7 +137,7 @@ } CGSize scaledSize = size; - CGPoint thumbnailPoint = CGPointZero; + CGPoint thumbnailPoint = CGPointZero; CGFloat widthFactor = size.width / self.size.width; CGFloat heightFactor = size.height / self.size.height; @@ -138,8 +167,8 @@ } UIGraphicsEndImageContext(); - - return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; + + return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; } @end