/* * This file is part of the SDWebImage package. * (c) Olivier Poitrey * (c) Laurin Brandner * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ #import "UIImage+GIF.h" #import #import "objc/runtime.h" #import "NSImage+WebCache.h" @implementation UIImage (GIF) + (UIImage *)sd_animatedGIFWithData:(NSData *)data { if (!data) { return nil; } #if SD_MAC return [[UIImage alloc] initWithData:data]; #else CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); size_t count = CGImageSourceGetCount(source); UIImage *staticImage; if (count <= 1) { staticImage = [[UIImage alloc] initWithData:data]; } else { // we will only retrieve the 1st frame. the full GIF support is available via the FLAnimatedImageView category. // this here is only code to allow drawing animated images as static ones //#if SD_WATCH // CGFloat scale = 1; // scale = [WKInterfaceDevice currentDevice].screenScale; //#elif SD_UIKIT // CGFloat scale = 1; // scale = [UIScreen mainScreen].scale; //#endif // // CGImageRef CGImage = CGImageSourceCreateImageAtIndex(source, 0, NULL); //#if SD_UIKIT || SD_WATCH // UIImage *frameImage = [UIImage imageWithCGImage:CGImage scale:scale orientation:UIImageOrientationUp]; // staticImage = [UIImage animatedImageWithImages:@[frameImage] duration:0.0f]; //#endif // CGImageRelease(CGImage); staticImage = [self getGifImage:data withSource:source withCount:count]; } CFRelease(source); return staticImage; #endif } + (UIImage *)getGifImage:(NSData *)data withSource:(CGImageSourceRef )source withCount:(size_t )count{ UIImage * animationImage; if (count <= 1) { animationImage = [[UIImage alloc] initWithData:data]; } else { NSMutableArray * imageArray = [NSMutableArray arrayWithCapacity:count]; NSTimeInterval duration = 0.0f; //遍历获取每一张图片 for (size_t i = 0; i < count; i++) { //解析图片拿到图片画笔拿到图片画笔 CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL); duration += [self imageDurationAtIndex:i source:source]; //scale:图片缩放因子 默认1 orientation:图片绘制方向 默认网上 [imageArray addObject:[UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; CGImageRelease(imageRef); } //如果没有抓取到图片播放时间,则按照0.1秒一张的方式来了播放 if (!duration) { duration = (1.0f / 10.0f) * count; } animationImage = [UIImage animatedImageWithImages:imageArray duration:duration]; } return animationImage; } +(float)imageDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { float imageDuration = 0.1f; //获取指定图像的属性信息 如宽、高、持续时间等都在里面 详情参考 CGImageProperties CFDictionaryRef cfImageProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); if (!cfImageProperties) { return imageDuration; } NSDictionary * imageProperties = (__bridge NSDictionary *) cfImageProperties; //拿到gif图的属性信息 获取每一帧的时间 NSDictionary * gifProperties = [imageProperties valueForKey:(NSString *)kCGImagePropertyGIFDictionary]; NSNumber * delayTime = [gifProperties valueForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; if (delayTime != nil) { return delayTime.floatValue; } return imageDuration; } - (BOOL)isGIF { return (self.images != nil); } @end