123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //
- // YYFrameImage.m
- // YYImage <https://github.com/ibireme/YYImage>
- //
- // Created by ibireme on 14/12/9.
- // Copyright (c) 2015 ibireme.
- //
- // This source code is licensed under the MIT-style license found in the
- // LICENSE file in the root directory of this source tree.
- //
- #import "YYFrameImage.h"
- #import "YYImageCoder.h"
- /**
- Return the path scale.
-
- e.g.
- <table>
- <tr><th>Path </th><th>Scale </th></tr>
- <tr><td>"icon.png" </td><td>1 </td></tr>
- <tr><td>"icon@2x.png" </td><td>2 </td></tr>
- <tr><td>"icon@2.5x.png" </td><td>2.5 </td></tr>
- <tr><td>"icon@2x" </td><td>1 </td></tr>
- <tr><td>"icon@2x..png" </td><td>1 </td></tr>
- <tr><td>"icon@2x.png/" </td><td>1 </td></tr>
- </table>
- */
- static CGFloat _NSStringPathScale(NSString *string) {
- if (string.length == 0 || [string hasSuffix:@"/"]) return 1;
- NSString *name = string.stringByDeletingPathExtension;
- __block CGFloat scale = 1;
-
- NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil];
- [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
- if (result.range.location >= 3) {
- scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue;
- }
- }];
-
- return scale;
- }
- @implementation YYFrameImage {
- NSUInteger _loopCount;
- NSUInteger _oneFrameBytes;
- NSArray *_imagePaths;
- NSArray *_imageDatas;
- NSArray *_frameDurations;
- }
- - (instancetype)initWithImagePaths:(NSArray *)paths oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount {
- NSMutableArray *durations = [NSMutableArray new];
- for (int i = 0, max = (int)paths.count; i < max; i++) {
- [durations addObject:@(oneFrameDuration)];
- }
- return [self initWithImagePaths:paths frameDurations:durations loopCount:loopCount];
- }
- - (instancetype)initWithImagePaths:(NSArray *)paths frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount {
- if (paths.count == 0) return nil;
- if (paths.count != frameDurations.count) return nil;
-
- NSString *firstPath = paths[0];
- NSData *firstData = [NSData dataWithContentsOfFile:firstPath];
- CGFloat scale = _NSStringPathScale(firstPath);
- UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] yy_imageByDecoded];
- self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp];
- if (!self) return nil;
- long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage);
- _oneFrameBytes = (NSUInteger)frameByte;
- _imagePaths = paths.copy;
- _frameDurations = frameDurations.copy;
- _loopCount = loopCount;
-
- return self;
- }
- - (instancetype)initWithImageDataArray:(NSArray *)dataArray oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount {
- NSMutableArray *durations = [NSMutableArray new];
- for (int i = 0, max = (int)dataArray.count; i < max; i++) {
- [durations addObject:@(oneFrameDuration)];
- }
- return [self initWithImageDataArray:dataArray frameDurations:durations loopCount:loopCount];
- }
- - (instancetype)initWithImageDataArray:(NSArray *)dataArray frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount {
- if (dataArray.count == 0) return nil;
- if (dataArray.count != frameDurations.count) return nil;
-
- NSData *firstData = dataArray[0];
- CGFloat scale = [UIScreen mainScreen].scale;
- UIImage *firstCG = [[[UIImage alloc] initWithData:firstData] yy_imageByDecoded];
- self = [self initWithCGImage:firstCG.CGImage scale:scale orientation:UIImageOrientationUp];
- if (!self) return nil;
- long frameByte = CGImageGetBytesPerRow(firstCG.CGImage) * CGImageGetHeight(firstCG.CGImage);
- _oneFrameBytes = (NSUInteger)frameByte;
- _imageDatas = dataArray.copy;
- _frameDurations = frameDurations.copy;
- _loopCount = loopCount;
-
- return self;
- }
- #pragma mark - YYAnimtedImage
- - (NSUInteger)animatedImageFrameCount {
- if (_imagePaths) {
- return _imagePaths.count;
- } else if (_imageDatas) {
- return _imageDatas.count;
- } else {
- return 1;
- }
- }
- - (NSUInteger)animatedImageLoopCount {
- return _loopCount;
- }
- - (NSUInteger)animatedImageBytesPerFrame {
- return _oneFrameBytes;
- }
- - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
- if (_imagePaths) {
- if (index >= _imagePaths.count) return nil;
- NSString *path = _imagePaths[index];
- CGFloat scale = _NSStringPathScale(path);
- NSData *data = [NSData dataWithContentsOfFile:path];
- return [[UIImage imageWithData:data scale:scale] yy_imageByDecoded];
- } else if (_imageDatas) {
- if (index >= _imageDatas.count) return nil;
- NSData *data = _imageDatas[index];
- return [[UIImage imageWithData:data scale:[UIScreen mainScreen].scale] yy_imageByDecoded];
- } else {
- return index == 0 ? self : nil;
- }
- }
- - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
- if (index >= _frameDurations.count) return 0;
- NSNumber *num = _frameDurations[index];
- return [num doubleValue];
- }
- @end
|