YYFrameImage.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //
  2. // YYFrameImage.m
  3. // YYKit <https://github.com/ibireme/YYKit>
  4. //
  5. // Created by ibireme on 14/12/9.
  6. // Copyright (c) 2015 ibireme.
  7. //
  8. // This source code is licensed under the MIT-style license found in the
  9. // LICENSE file in the root directory of this source tree.
  10. //
  11. #import "YYFrameImage.h"
  12. #import "NSString+YYAdd.h"
  13. #import "UIImage+YYAdd.h"
  14. #import "YYImageCoder.h"
  15. @implementation YYFrameImage {
  16. NSUInteger _loopCount;
  17. NSUInteger _oneFrameBytes;
  18. NSArray *_imagePaths;
  19. NSArray *_imageDatas;
  20. NSArray *_frameDurations;
  21. }
  22. - (instancetype)initWithImagePaths:(NSArray *)paths oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount {
  23. NSMutableArray *durations = [NSMutableArray new];
  24. for (int i = 0, max = (int)paths.count; i < max; i++) {
  25. [durations addObject:@(oneFrameDuration)];
  26. }
  27. return [self initWithImagePaths:paths frameDurations:durations loopCount:loopCount];
  28. }
  29. - (instancetype)initWithImagePaths:(NSArray *)paths frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount {
  30. if (paths.count == 0) return nil;
  31. if (paths.count != frameDurations.count) return nil;
  32. NSString *firstPath = paths[0];
  33. NSData *firstData = [NSData dataWithContentsOfFile:firstPath];
  34. CGFloat scale = firstPath.pathScale;
  35. UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] imageByDecoded];
  36. self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp];
  37. if (!self) return nil;
  38. long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage);
  39. _oneFrameBytes = (NSUInteger)frameByte;
  40. _imagePaths = paths.copy;
  41. _frameDurations = frameDurations.copy;
  42. _loopCount = loopCount;
  43. return self;
  44. }
  45. - (instancetype)initWithImageDataArray:(NSArray *)dataArray oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount {
  46. NSMutableArray *durations = [NSMutableArray new];
  47. for (int i = 0, max = (int)dataArray.count; i < max; i++) {
  48. [durations addObject:@(oneFrameDuration)];
  49. }
  50. return [self initWithImageDataArray:dataArray frameDurations:durations loopCount:loopCount];
  51. }
  52. - (instancetype)initWithImageDataArray:(NSArray *)dataArray frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount {
  53. if (dataArray.count == 0) return nil;
  54. if (dataArray.count != frameDurations.count) return nil;
  55. NSData *firstData = dataArray[0];
  56. CGFloat scale = [UIScreen mainScreen].scale;
  57. UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] imageByDecoded];
  58. self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp];
  59. if (!self) return nil;
  60. long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage);
  61. _oneFrameBytes = (NSUInteger)frameByte;
  62. _imageDatas = dataArray.copy;
  63. _frameDurations = frameDurations.copy;
  64. _loopCount = loopCount;
  65. return self;
  66. }
  67. #pragma mark - YYAnimtedImage
  68. - (NSUInteger)animatedImageFrameCount {
  69. if (_imagePaths) {
  70. return _imagePaths.count;
  71. } else if (_imageDatas) {
  72. return _imageDatas.count;
  73. } else {
  74. return 1;
  75. }
  76. }
  77. - (NSUInteger)animatedImageLoopCount {
  78. return _loopCount;
  79. }
  80. - (NSUInteger)animatedImageBytesPerFrame {
  81. return _oneFrameBytes;
  82. }
  83. - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
  84. if (_imagePaths) {
  85. if (index >= _imagePaths.count) return nil;
  86. NSString *path = _imagePaths[index];
  87. CGFloat scale = [path pathScale];
  88. NSData *data = [NSData dataWithContentsOfFile:path];
  89. return [[UIImage imageWithData:data scale:scale] imageByDecoded];
  90. } else if (_imageDatas) {
  91. if (index >= _imageDatas.count) return nil;
  92. NSData *data = _imageDatas[index];
  93. return [[UIImage imageWithData:data scale:[UIScreen mainScreen].scale] imageByDecoded];
  94. } else {
  95. return index == 0 ? self : nil;
  96. }
  97. }
  98. - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
  99. if (index >= _frameDurations.count) return 0;
  100. NSNumber *num = _frameDurations[index];
  101. return [num doubleValue];
  102. }
  103. @end