当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS开发中实现显示gif图片的方法

iOS开发中实现显示gif图片的方法

2019年07月24日  | 移动技术网IT编程  | 我要评论

保定网,小学德育案例,闻一多的资料

我们知道gif是由一阵阵画面组成的,而且每一帧画面播放的时常可能会不相等,观察上面两个例子,发现他们都没有对gif中每一帧的显示时常做处理,这样的结果就是整个gif中每一帧画面都是以固定的速度向前播放,很显然这并不总会符合需求。
 
  于是自己写一个解析gif的工具类,解决每一帧画面并遵循每一帧所对应的显示时间进行播放。
 
  程序的思路如下:
 
  1、首先使用imageio库中的cgimagesource家在gif文件。
 
  2、通过cgimagesource获取到gif文件中的总的帧数,以及每一帧的显示时间。
 
  3、通过cakeyframeanimation来完成gif动画的播放。
 
  下面直接上我写的解析和播放gif的工具类的代码:
 

复制代码 代码如下:

//
//  svgifview.h
//  svgifsample
//
//  created by maple on 3/28/13.
//  copyright (c) 2013 smileevday. all rights reserved.
//


#import <uikit/uikit.h>

@interface svgifview : uiview


/*
 * @brief desingated initializer
 */
- (id)initwithcenter:(cgpoint)center fileurl:(nsurl*)fileurl;

/*
 * @brief start gif animation
 */
- (void)startgif;

/*
 * @brief stop gif animation
 */
- (void)stopgif;

/*
 * @brief get frames image(cgimageref) in gif
 */
+ (nsarray*)framesingif:(nsurl*)fileurl;


@end


//
//  svgifview.m
//  svgifsample
//
//  created by maple on 3/28/13.
//  copyright (c) 2013 smileevday. all rights reserved.
//

#import "svgifview.h"
#import <imageio/imageio.h>
#import <quartzcore/coreanimation.h>

/*
 * @brief resolving gif information
 */
void getframeinfo(cfurlref url, nsmutablearray *frames, nsmutablearray *delaytimes, cgfloat *totaltime,cgfloat *gifwidth, cgfloat *gifheight)
{
    cgimagesourceref gifsource = cgimagesourcecreatewithurl(url, null);
   
    // get frame count
    size_t framecount = cgimagesourcegetcount(gifsource);
    for (size_t i = 0; i < framecount; ++i) {
        // get each frame
        cgimageref frame = cgimagesourcecreateimageatindex(gifsource, i, null);
        [frames addobject:(id)frame];
        cgimagerelease(frame);
       
        // get gif info with each frame
        nsdictionary *dict = (nsdictionary*)cgimagesourcecopypropertiesatindex(gifsource, i, null);
        nslog(@"kcgimagepropertygifdictionary %@", [dict valueforkey:(nsstring*)kcgimagepropertygifdictionary]);
       
        // get gif size
        if (gifwidth != null && gifheight != null) {
            *gifwidth = [[dict valueforkey:(nsstring*)kcgimagepropertypixelwidth] floatvalue];
            *gifheight = [[dict valueforkey:(nsstring*)kcgimagepropertypixelheight] floatvalue];
        }
       
        // kcgimagepropertygifdictionary中kcgimagepropertygifdelaytime,kcgimagepropertygifunclampeddelaytime值是一样的
        nsdictionary *gifdict = [dict valueforkey:(nsstring*)kcgimagepropertygifdictionary];
        [delaytimes addobject:[gifdict valueforkey:(nsstring*)kcgimagepropertygifdelaytime]];
       
        if (totaltime) {
            *totaltime = *totaltime + [[gifdict valueforkey:(nsstring*)kcgimagepropertygifdelaytime] floatvalue];
        }
    }
}

@interface svgifview() {
    nsmutablearray *_frames;
    nsmutablearray *_framedelaytimes;
   
    cgfloat _totaltime;         // seconds
    cgfloat _width;
    cgfloat _height;
}

@end

@implementation svgifview


- (id)initwithcenter:(cgpoint)center fileurl:(nsurl*)fileurl;
{
    self = [super initwithframe:cgrectzero];
    if (self) {
       
        _frames = [[nsmutablearray alloc] init];
        _framedelaytimes = [[nsmutablearray alloc] init];
       
        _width = 0;
        _height = 0;
       
        if (fileurl) {
            getframeinfo((cfurlref)fileurl, _frames, _framedelaytimes, &_totaltime, &_width, &_height);
        }
       
        self.frame = cgrectmake(0, 0, _width, _height);
        self.center = center;
    }
   
    return self;
}

+ (nsarray*)framesingif:(nsurl *)fileurl
{
    nsmutablearray *frames = [nsmutablearray arraywithcapacity:3];
    nsmutablearray *delays = [nsmutablearray arraywithcapacity:3];
   
    getframeinfo((cfurlref)fileurl, frames, delays, null, null, null);
   
    return frames;
}

- (void)startgif
{
    cakeyframeanimation *animation = [cakeyframeanimation animationwithkeypath:@"contents"];
   
    nsmutablearray *times = [nsmutablearray arraywithcapacity:3];
    cgfloat currenttime = 0;
    int count = _framedelaytimes.count;
    for (int i = 0; i < count; ++i) {
        [times addobject:[nsnumber numberwithfloat:(currenttime / _totaltime)]];
        currenttime += [[_framedelaytimes objectatindex:i] floatvalue];
    }
    [animation setkeytimes:times];
   
    nsmutablearray *images = [nsmutablearray arraywithcapacity:3];
    for (int i = 0; i < count; ++i) {
        [images addobject:[_frames objectatindex:i]];
    }
   
    [animation setvalues:images];
    [animation settimingfunction:[camediatimingfunction functionwithname:kcamediatimingfunctionlinear]];
    animation.duration = _totaltime;
    animation.delegate = self;
    animation.repeatcount = 5;
   
    [self.layer addanimation:animation forkey:@"gifanimation"];
}

- (void)stopgif
{
    [self.layer removeallanimations];
}

// remove contents when animation end
- (void)animationdidstop:(caanimation *)anim finished:(bool)flag
{
    self.layer.contents = nil;
}

// only override drawrect: if you perform custom drawing.
// an empty implementation adversely affects performance during animation.
- (void)drawrect:(cgrect)rect
{
    // drawing code
}


@end


  代码很短也比较容易,就不一一解释了。最开始的那个c函数主要就是用来解析gif的,之所以用c函数是因为我要返回多个信息,而objective-c只能返回一个参数,而且objective-c和c语言可以很方便的混合编程。

另外再介绍两种使用uiimageview的方法:

1. 使用uiwebview播放

复制代码 代码如下:

    // 设定位置和大小
    cgrect frame = cgrectmake(50,50,0,0);
    frame.size = [uiimage imagenamed:@"guzhang.gif"].size;
    // 读取gif图片数据
    nsdata *gif = [nsdata datawithcontentsoffile: [[nsbundle mainbundle] pathforresource:@"guzhang" oftype:@"gif"]];
    // view生成
    uiwebview *webview = [[uiwebview alloc] initwithframe:frame];
    webview.userinteractionenabled = no;//用户不可交互
    [webview loaddata:gif mimetype:@"image/gif" textencodingname:nil baseurl:nil];
    [self.view addsubview:webview];
    [webview release];

2.将gif图片分解成多张png图片,使用uiimageview播放。
代码如下:

复制代码 代码如下:

 uiimageview *gifimageview = [[uiimageview alloc] initwithframe:[[uiscreen mainscreen] bounds]];
    nsarray *gifarray = [nsarray arraywithobjects:[uiimage imagenamed:@"1"],
                                                  [uiimage imagenamed:@"2"],
                                                  [uiimage imagenamed:@"3"],
                                                  [uiimage imagenamed:@"4"],
                                                  [uiimage imagenamed:@"5"],
                                                  [uiimage imagenamed:@"6"],
                                                  [uiimage imagenamed:@"7"],
                                                  [uiimage imagenamed:@"8"],
                                                  [uiimage imagenamed:@"9"],
                                                  [uiimage imagenamed:@"10"],
                                                  [uiimage imagenamed:@"11"],
                                                  [uiimage imagenamed:@"12"],
                                                  [uiimage imagenamed:@"13"],
                                                  [uiimage imagenamed:@"14"],
                                                  [uiimage imagenamed:@"15"],
                                                  [uiimage imagenamed:@"16"],
                                                  [uiimage imagenamed:@"17"],
                                                  [uiimage imagenamed:@"18"],
                                                  [uiimage imagenamed:@"19"],
                                                  [uiimage imagenamed:@"20"],
                                                  [uiimage imagenamed:@"21"],
                                                  [uiimage imagenamed:@"22"],nil];
    gifimageview.animationimages = gifarray; //动画图片数组
    gifimageview.animationduration = 5; //执行一次完整动画所需的时长
    gifimageview.animationrepeatcount = 1;  //动画重复次数
    [gifimageview startanimating];
    [self.view addsubview:gifimageview];
    [gifimageview release];

注意:这个方法,如果gif动画每桢间的时间间隔不同,不能达到此效果。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网