UIImage+GIF.m 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * This file is part of the SDWebImage package.
  3. * (c) Olivier Poitrey <rs@dailymotion.com>
  4. * (c) Laurin Brandner
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. #import "UIImage+GIF.h"
  10. #import <ImageIO/ImageIO.h>
  11. #import "objc/runtime.h"
  12. #import "NSImage+WebCache.h"
  13. @implementation UIImage (GIF)
  14. + (UIImage *)sd_animatedGIFWithData:(NSData *)data {
  15. if (!data) {
  16. return nil;
  17. }
  18. #if SD_MAC
  19. return [[UIImage alloc] initWithData:data];
  20. #else
  21. CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
  22. size_t count = CGImageSourceGetCount(source);
  23. UIImage *staticImage;
  24. if (count <= 1) {
  25. staticImage = [[UIImage alloc] initWithData:data];
  26. } else {
  27. // we will only retrieve the 1st frame. the full GIF support is available via the FLAnimatedImageView category.
  28. // this here is only code to allow drawing animated images as static ones
  29. //#if SD_WATCH
  30. // CGFloat scale = 1;
  31. // scale = [WKInterfaceDevice currentDevice].screenScale;
  32. //#elif SD_UIKIT
  33. // CGFloat scale = 1;
  34. // scale = [UIScreen mainScreen].scale;
  35. //#endif
  36. //
  37. // CGImageRef CGImage = CGImageSourceCreateImageAtIndex(source, 0, NULL);
  38. //#if SD_UIKIT || SD_WATCH
  39. // UIImage *frameImage = [UIImage imageWithCGImage:CGImage scale:scale orientation:UIImageOrientationUp];
  40. // staticImage = [UIImage animatedImageWithImages:@[frameImage] duration:0.0f];
  41. //#endif
  42. // CGImageRelease(CGImage);
  43. staticImage = [self getGifImage:data withSource:source withCount:count];
  44. }
  45. CFRelease(source);
  46. return staticImage;
  47. #endif
  48. }
  49. + (UIImage *)getGifImage:(NSData *)data withSource:(CGImageSourceRef )source withCount:(size_t )count{
  50. UIImage * animationImage;
  51. if (count <= 1) {
  52. animationImage = [[UIImage alloc] initWithData:data];
  53. }
  54. else {
  55. NSMutableArray * imageArray = [NSMutableArray arrayWithCapacity:count];
  56. NSTimeInterval duration = 0.0f;
  57. //遍历获取每一张图片
  58. for (size_t i = 0; i < count; i++) {
  59. //解析图片拿到图片画笔拿到图片画笔
  60. CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
  61. duration += [self imageDurationAtIndex:i source:source];
  62. //scale:图片缩放因子 默认1 orientation:图片绘制方向 默认网上
  63. [imageArray addObject:[UIImage imageWithCGImage:imageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
  64. CGImageRelease(imageRef);
  65. }
  66. //如果没有抓取到图片播放时间,则按照0.1秒一张的方式来了播放
  67. if (!duration) {
  68. duration = (1.0f / 10.0f) * count;
  69. }
  70. animationImage = [UIImage animatedImageWithImages:imageArray duration:duration];
  71. }
  72. return animationImage;
  73. }
  74. +(float)imageDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
  75. float imageDuration = 0.1f;
  76. //获取指定图像的属性信息 如宽、高、持续时间等都在里面 详情参考 CGImageProperties
  77. CFDictionaryRef cfImageProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
  78. if (!cfImageProperties) {
  79. return imageDuration;
  80. }
  81. NSDictionary * imageProperties = (__bridge NSDictionary *) cfImageProperties;
  82. //拿到gif图的属性信息 获取每一帧的时间
  83. NSDictionary * gifProperties = [imageProperties valueForKey:(NSString *)kCGImagePropertyGIFDictionary];
  84. NSNumber * delayTime = [gifProperties valueForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
  85. if (delayTime != nil) {
  86. return delayTime.floatValue;
  87. }
  88. return imageDuration;
  89. }
  90. - (BOOL)isGIF {
  91. return (self.images != nil);
  92. }
  93. @end