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来做。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值