iOS:GIF图片的预览以及生成

需求

需要在ios平台上实现GIF图片的展示以及生成

展示需求

通过调研发现有两种方式来实现

1. 根据gif的格式来自己解析出图片,或者使用ImageMagick这个库来做 2. 使用sdk当中自带的ImageIO来做,但是需要iOS系统版本4.0以上(这个基本上木有问题了,因为现在xcode默认是4.3以上了)

解决

这里使用了ImageIO来做,基本上很简单,直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
NSData* data = [NSData dataWithContentOfFile:@"some.gif"]; CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)data, NULL); size_t count = CGImageSourceGetCount(source);  NSMutableArray* tmpArray = [NSMutableArray array]; for (size_t i = 0; i < count; i++) {  CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);  image = [UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];  NSDictionary* frameProperties = [(NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, i, NULL) autorelease];  duration = [[[frameProperties objectForKey:(NSString*)kCGImagePropertyGIFDictionary] objectForKey:(NSString*)kCGImagePropertyGIFDelayTime] doubleValue];  duration = MAX(duration, 0.01);  [tmpArray addObject:image];  CGImageRelease(image); } CFRelease(source); self.imageFrameArray = nil; if (tmpArray.count > 1) {  self.imageFrameArray = tmpArray; } 

生成GIF

基本上方法也是和展示差不多就是ImageIO,或者是使用ImageMagick,这里我都做了测试,先上代码

使用ImageIO来生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#import "MagickWand.h" // Commented out starts here NSMutableData* imgData = [NSMutableData data]; CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imgData, kUTTypeGIF, imgs.count, NULL);  NSString* path = [[[DataCenter sharedDataCenter] getLibraryPath] stringByAppendingPathComponent:@"test.gif"]; CFURLRef url = CFURLCreateWithFileSystemPath (  kCFAllocatorDefault,  (CFStringRef)path,  kCFURLPOSIXPathStyle,  false); destination = CGImageDestinationCreateWithURL(url, kUTTypeGIF, imgs.count, NULL); NSDictionary *frameProperties = [NSDictionary  dictionaryWithObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:duration], (NSString *)kCGImagePropertyGIFDelayTime, nil]  forKey:(NSString *)kCGImagePropertyGIFDictionary]; NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:2]; [dict setObject:[NSNumber numberWithBool:YES] forKey:(NSString*)kCGImagePropertyGIFHasGlobalColorMap]; [dict setObject:(NSString *)kCGImagePropertyColorModelRGB forKey:(NSString *)kCGImagePropertyColorModel]; [dict setObject:[NSNumber numberWithInt:8] forKey:(NSString*)kCGImagePropertyDepth]; [dict setObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]; NSDictionary *gifProperties = [NSDictionary dictionaryWithObject:dict  forKey:(NSString *)kCGImagePropertyGIFDictionary]; for (UIImage* dImg in imgs) {  UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), FALSE, 1);  UIView* gifBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];  gifBgView.backgroundColor = [UIColor clearColor];  UIImageView* imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];  [imgView setBackgroundColor:[UIColor clearColor]];  [imgView setContentMode:UIViewContentModeScaleAspectFill];  [imgView setImage:self.image];  imgView.center = gifBgView.center;  [gifBgView addSubview:imgView];   UIImageView* dImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];  dImgView.center = imgView.center;  [dImgView setBackgroundColor:[UIColor clearColor]];  [dImgView setImage:dImg];  [dImgView setContentMode:UIViewContentModeScaleAspectFill];  [gifBgView addSubview:dImgView];   [[gifBgView layer] renderInContext:UIGraphicsGetCurrentContext()];   UIImage* img = UIGraphicsGetImageFromCurrentImageContext();  UIGraphicsEndImageContext();  CGImageDestinationAddImage(destination, img.CGImage, (__bridge CFDictionaryRef)frameProperties); } CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)gifProperties); CGImageDestinationFinalize(destination); CFRelease(destination); imgData = [NSData dataWithContentsOfFile:[[[DataCenter sharedDataCenter] getLibraryPath] stringByAppendingPathComponent:@"test.gif"]]; return imgData; 
使用ImageMagick来生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
MagickWandGenesis(); MagickWand* mw = NewMagickWand(); MagickSetImageFormat(mw, "gif"); for (UIImage* dImg in imgs) {  UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), FALSE, 1);  UIView* gifBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];  gifBgView.backgroundColor = [UIColor clearColor];  UIImageView* imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];  [imgView setBackgroundColor:[UIColor clearColor]];  [imgView setContentMode:UIViewContentModeScaleAspectFill];  [imgView setImage:self.image];  imgView.center = gifBgView.center;  [gifBgView addSubview:imgView];  UIImageView* dImgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];  dImgView.center = imgView.center;  [dImgView setBackgroundColor:[UIColor clearColor]];  [dImgView setImage:dImg];  [dImgView setContentMode:UIViewContentModeScaleAspectFill];  [gifBgView addSubview:dImgView];  [[gifBgView layer] renderInContext:UIGraphicsGetCurrentContext()];  UIImage* img = UIGraphicsGetImageFromCurrentImageContext();  UIGraphicsEndImageContext();  MagickWand* tempMW = NewMagickWand();  NSData* data = UIImageJPEGRepresentation(img, 1.0);  MagickReadImageBlob(tempMW, [data bytes], [data length]);  MagickSetImageDelay(tempMW, duration*100);  MagickAddImage(mw, tempMW);  tempMW = DestroyMagickWand(tempMW); } MagickWriteImages(mw, [[[[DataCenter sharedDataCenter] getLibraryPath] stringByAppendingPathComponent:@"test.gif"] cStringUsingEncoding:NSUTF8StringEncoding], MagickTrue); mw = DestroyMagickWand(mw); MagickWandTerminus(); NSData* imgData = [NSData dataWithContentsOfFile:[[[DataCenter sharedDataCenter] getLibraryPath] stringByAppendingPathComponent:@"test.gif"]]; return imgData; 
对比

这两个方法都能生成GIF图片,但是ImageIO的生成速度要比ImageMagick快上不少,不过测试上来看用ImageIO容易造成内存的warrning,还有就是使用ImageIO的话如果使用默认的color table那么生成的图片有的像素比较低,严重的会丢颜色。这也是为什么ImageIO要快的原因把。相比如果项目假设用户的等待时间不是很限制的话,个人推荐使用ImageMagick来做。

你可能感兴趣的:(iOS:GIF图片的预览以及生成)