From 08db889da10d72066f989f3e06620e74f1f823ce Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Tue, 14 Jul 2015 00:33:52 +0300 Subject: [PATCH] Switched UIImage+GIF to use FLAnimatedImage. Replaced #908 and added @3x support for the GIF imageNamed --- SDWebImage/UIImage+GIF.h | 2 - SDWebImage/UIImage+GIF.m | 169 +++++++++------------------------------ 2 files changed, 39 insertions(+), 132 deletions(-) diff --git a/SDWebImage/UIImage+GIF.h b/SDWebImage/UIImage+GIF.h index 00c5e6e..ea40ca4 100755 --- a/SDWebImage/UIImage+GIF.h +++ b/SDWebImage/UIImage+GIF.h @@ -8,8 +8,6 @@ + (UIImage *)sd_animatedGIFWithData:(NSData *)data; -- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size; - @end #endif diff --git a/SDWebImage/UIImage+GIF.m b/SDWebImage/UIImage+GIF.m index 129e1f5..70cac9c 100755 --- a/SDWebImage/UIImage+GIF.m +++ b/SDWebImage/UIImage+GIF.m @@ -7,147 +7,56 @@ @implementation UIImage (GIF) + (UIImage *)sd_animatedGIFWithData:(NSData *)data { - if (!data) { - return nil; - } - - CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); - - size_t count = CGImageSourceGetCount(source); - - UIImage *animatedImage; - - if (count <= 1) { - animatedImage = [[UIImage alloc] initWithData:data]; - } - else { - NSMutableArray *images = [NSMutableArray array]; - - NSTimeInterval duration = 0.0f; - - for (size_t i = 0; i < count; i++) { - CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); - - duration += [self sd_frameDurationAtIndex:i source:source]; - - [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; - - CGImageRelease(image); - } - - if (!duration) { - duration = (1.0f / 10.0f) * count; - } - - animatedImage = [UIImage animatedImageWithImages:images duration:duration]; - } - - CFRelease(source); - - return animatedImage; -} - -+ (float)sd_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; + return [FLAnimatedImage imageWithData:data]; } + (UIImage *)sd_animatedGIFNamed:(NSString *)name { CGFloat scale = [UIScreen mainScreen].scale; - - if (scale > 1.0f) { - NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"]; - - NSData *data = [NSData dataWithContentsOfFile:retinaPath]; - - if (data) { - return [UIImage sd_animatedGIFWithData:data]; - } - - NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; - + + //set up possible paths + NSString *threeTimesResName = [name stringByAppendingString:@"@3x"]; + NSString *twoTimesResName = [name stringByAppendingString:@"@2x"]; + NSString *normalResName = name; + + NSData *data; + NSString *path; + + //get gif for @3x display + if (scale > 2.0f) { + path = [[NSBundle mainBundle] pathForResource:threeTimesResName ofType:@"gif"]; data = [NSData dataWithContentsOfFile:path]; - - if (data) { - return [UIImage sd_animatedGIFWithData:data]; - } - - return [UIImage imageNamed:name]; } - else { - NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; - - NSData *data = [NSData dataWithContentsOfFile:path]; - - if (data) { - return [UIImage sd_animatedGIFWithData:data]; - } - - return [UIImage imageNamed:name]; + + //get gif for 2x display or if there is no @3x resource + if (scale > 1.0f && !data) { + path = [[NSBundle mainBundle] pathForResource:twoTimesResName ofType:@"gif"]; + data = [NSData dataWithContentsOfFile:path]; } -} - -- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size { - if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) { - return self; + + //get gif for non-retina display or if there is no @2x or 3x resource + if (!data) { + path = [[NSBundle mainBundle] pathForResource:normalResName ofType:@"gif"]; + data = [NSData dataWithContentsOfFile:path]; } - - CGSize scaledSize = size; - CGPoint thumbnailPoint = CGPointZero; - - CGFloat widthFactor = size.width / self.size.width; - CGFloat heightFactor = size.height / self.size.height; - CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor; - scaledSize.width = self.size.width * scaleFactor; - scaledSize.height = self.size.height * scaleFactor; - - if (widthFactor > heightFactor) { - thumbnailPoint.y = (size.height - scaledSize.height) * 0.5; + + //no data yet? maybe there is only a @2x image + if (!data) { + path = [[NSBundle mainBundle] pathForResource:twoTimesResName ofType:@"gif"]; + data = [NSData dataWithContentsOfFile:path]; } - else if (widthFactor < heightFactor) { - thumbnailPoint.x = (size.width - scaledSize.width) * 0.5; + + //still no data? could be only a @3x image is provided + if (!data) { + path = [[NSBundle mainBundle] pathForResource:threeTimesResName ofType:@"gif"]; + data = [NSData dataWithContentsOfFile:path]; } - - NSMutableArray *scaledImages = [NSMutableArray array]; - - UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); - - for (UIImage *image in self.images) { - [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)]; - UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); - - [scaledImages addObject:newImage]; + + if (data) { + return [UIImage sd_animatedGIFWithData:data]; } - - UIGraphicsEndImageContext(); - - return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; + + //still no resource found --> try to return non-gif image + return [UIImage imageNamed:name]; } @end