UIImageView 播放 GIF

来源:互联网 发布:淘宝韩国第一美女模特 编辑:程序博客网 时间:2024/05/16 09:16

<span style="font-family: Arial, Helvetica, sans-serif;"></span><span style="font-family: Arial, Helvetica, sans-serif; "><strong><span style="font-size:18px;">本文主要解析GIF图片的每一帧,然后用定时器循环播放实现GIF动画。</span></strong></span>

源于这篇GIF动画的深思,还是一些需求产生的:如,我只想看GIF动画播放一次(2,3,4...),然后做其他事;或者动画每帧间隔太慢了,想调整怎么办?等等。。。,作为程序员,大家想要的感觉就是,一切尽在我的掌控之中,我想要停就马上停止,想要动就立刻动起来。不好的情况是,我没法控制它,我想要干另外一件事了,它还不能停止。


在iOS平台,大家所熟知的有三种播放方式:

1、用UIWebView 实现:也是比较简单的方式,这种方式主要就是把GIF图片构造入一个html中,然后让UIWebView去解析这个html,然后播放动画。

这种方式的缺点:使用者无法知道这个动画循环一次完成,反正是uiwebview解析,我只看到动画,其他的无法控制。

2、UIImageView自身支持的动画:简单的把GIF每一帧图片解析出来,然后生成UIImage数组,

self.imageView.animationImages = imagesArray;

 self.imageView.animationDuration = imageDuration;

   [self.imageViewstartAnimating];

然后就可以动画就开始了,或者使用CAKeyframeAnimation 也可以。这几个都一样的是我们都要解析GIF内的每一帧图片,然后组成一个图片数组来播放动画。

缺点:GIF由很多帧图片组成,然后播放时有个播放帧时间间隔,每一帧的间隔是不一样的。若是上面这种方式的动画播放,它就会设置一个平均每帧时间,这样播放出来的动画也许就不是原来的效果了。

更严重的是GIF图片稍大一点内存就暴涨,一个600KB的GIF解析出来后由50张UIImage,这时候内存会涨到70MB,及时这个应用什么也不干;刚开始我发现好像也能接受,但我们有一个5MB的GIF,解析后有200多张UIImage,这时候内存一下涨到200MB,马上应用就crash了。

 

 3、利用CADisplayLink或NSTimer循环播放:也就是我更推荐的一种

存储图片信息采用 CGImageSourceRef:

<span style="font-size:18px;">   <span style="white-space:pre"></span>_gifSourceRef = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:gifPath], NULL);   <span style="white-space:pre"></span> self.frameCount = CGImageSourceGetCount(_gifSourceRef);</span>
</pre><pre name="code" class="objc">
然后在定时器中不断更新图片,根据每一帧的间隔来更换,就可以达到效果:

<span style="font-size:18px;"> <span style="white-space:pre"></span>CGImageRef ref = CGImageSourceCreateImageAtIndex(_gifSourceRef, self.currentFrameIndex, NULL);        self.layer.contents = (__bridge id)(ref);        CGImageRelease(ref);</span>

解析每一帧的时间可以用下面的方法:

<span style="font-size:18px;">- (float)frameDurationAtIndex:(size_t)index{    CFDictionaryRef dictRef = CGImageSourceCopyPropertiesAtIndex(_gifSourceRef, index, NULL);    NSDictionary *dict = (__bridge NSDictionary *)dictRef;    NSDictionary *gifDict = (dict[(NSString *)kCGImagePropertyGIFDictionary]);    NSNumber *unclampedDelayTime = gifDict[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];    NSNumber *delayTime = gifDict[(NSString *)kCGImagePropertyGIFDelayTime];    CFRelease(dictRef);        if (unclampedDelayTime.floatValue) {        return unclampedDelayTime.floatValue;    }else if (delayTime.floatValue) {        return delayTime.floatValue;    }else{        return 1/30.f;    }}</span>

这样我们就可以在定时器响应函数里做处理来更换图片,实现动画。


若想看详细实现源码,请看GitHubDemo,主要实现第三种播放方式,因为在内存方面,保持原动画效果更好的方式(每一帧的间隔)。












   







0 0
原创粉丝点击