开发时遇到一个需求,就是要多个gif合并播放
1、单个gif播放
#import <UIImage+GIF.h>
NSString *path = [[NSBundle mainBundle] pathForResource:@"gif" ofType:@"gif"];
NSData *imgData = [NSData dataWithContentsOfFile:path];
self.image.image = [UIImage sd_animatedGIFWithData:imgData];
查看 <UIImage+GIF.h>,发现只是用了简单的封装
#import "UIImage+GIF.h"
#import "SDWebImageGIFCoder.h"
#import "NSImage+WebCache.h"
@implementation UIImage (GIF)
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {
if (!data) {
return nil;
}
return [[SDWebImageGIFCoder sharedCoder] decodedImageWithData:data];
}
- (BOOL)isGIF {
return (self.images != nil);
}
@end
继续查看 SDWebImageGIFCoder.h ,发现 gif 转UIImage主要用到了这个方法:
(UIImage *)decodedImageWithData:(NSData *)data
- (UIImage *)decodedImageWithData:(NSData *)data {
if (!data) {
return nil;
}
#if SD_MAC
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
NSImage *animatedImage = [[NSImage alloc] initWithSize:imageRep.size];
[animatedImage addRepresentation:imageRep];
return animatedImage;
#else
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
if (!source) {
return nil;
}
size_t count = CGImageSourceGetCount(source);
UIImage *animatedImage;
if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
} else {
NSMutableArray<SDWebImageFrame *> *frames = [NSMutableArray array];
for (size_t i = 0; i < count; i++) {
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
if (!imageRef) {
continue;
}
float duration = [self sd_frameDurationAtIndex:i source:source];
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
SDWebImageFrame *frame = [SDWebImageFrame frameWithImage:image duration:duration];
[frames addObject:frame];
}
NSUInteger loopCount = 1;
NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(source, nil);
NSDictionary *gifProperties = [imageProperties valueForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary];
if (gifProperties) {
NSNumber *gifLoopCount = [gifProperties valueForKey:(__bridge NSString *)kCGImagePropertyGIFLoopCount];
if (gifLoopCount != nil) {
loopCount = gifLoopCount.unsignedIntegerValue;
}
}
animatedImage = [SDWebImageCoderHelper animatedImageWithFrames:frames];
animatedImage.sd_imageLoopCount = loopCount;
animatedImage.sd_imageFormat = SDImageFormatGIF;
}
CFRelease(source);
return animatedImage;
#endif
}
2、多个gif合并
基于SDWebImageGIFCoder 新建一个category,添加下面的方法
ps: 部分方法和头文件引用请直接复制SDWebImageGIFCoder.m !!!
- (UIImage *)decodedImageWithDatas:(NSArray<NSData *>*)datas {
UIImage *animatedImage;
switch (datas.count) {
case 0:
return nil;
case 1:
{
animatedImage = [[UIImage alloc] initWithData:datas.firstObject];
}
break;
default:
{
NSMutableArray<SDWebImageFrame *> *frames = [NSMutableArray array];
for (NSUInteger i = 0; i < datas.count; ++i) {
NSData *data = datas[i];
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
if (!source) {
return nil;
}
size_t count = CGImageSourceGetCount(source);
if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
} else {
for (size_t i = 0; i < count; i++) {
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
if (!imageRef) {
continue;
}
float duration = [self sd_frameDurationAtIndex:i source:source];
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
SDWebImageFrame *frame = [SDWebImageFrame frameWithImage:image duration:duration];
[frames addObject:frame];
}
}
CFRelease(source);
}
NSUInteger loopCount = 1;
animatedImage = [SDWebImageCoderHelper animatedImageWithFrames:frames];
animatedImage.sd_imageLoopCount = loopCount;
animatedImage.sd_imageFormat = SDImageFormatGIF;
}
break;
}
return animatedImage;
}
根据多个 gif 数据获取 image
NSMutableArray<NSData *> *datas = [NSMutableArray new];
for (NSUInteger i = 0; i < gifs.count; ++i) {
NSString *path = [[NSBundle mainBundle] pathForResource:gifs[i] ofType:@"gif"];
NSData *imgData = [NSData dataWithContentsOfFile:path];
[datas addObject:imgData];
}
self.imageView.image = [[SDWebImageGIFCoder sharedCoder] decodedImageWithDatas:datas];
网友评论