• iOS加载Gif图片


    转载请注明出处!!!

    Gif图片是非常常见的图片格式,尤其是在聊天的过程中,Gif表情使用地很频繁。但是iOS竟然没有现成的支持加载和播放Gif的类。

    简单地汇总了一下,大概有以下几种方法:

    1、使用UIWebView,但是这种方法比较耗内存。

    // 读取gif图片数据 
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,200,200)];
    [self.view addSubview:webView];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"001" ofType:@"gif"];
    /*
    NSData *data = [NSData dataWithContentsOfFile:path];
    使用loadData:MIMEType:textEncodingName: 则有警告
    [webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
    */
    NSURL *url = [NSURL URLWithString:path];
    [webView loadRequest:[NSURLRequest requestWithURL:url]]; 

    但是使用UIWebView的弊端在于,不能设置Gif动画的播放时间。

    2、将Gif拆分成多张图片,使用UIImageView播放。

    最好把所需要的Gif图片打包到Bundle文件内,如下图所示


    Loading.png

    - (NSArray *)animationImages
    {
    NSFileManager *fielM = [NSFileManager defaultManager];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Loading" ofType:@"bundle"];
    NSArray *arrays = [fielM contentsOfDirectoryAtPath:path error:nil];
    
    NSMutableArray *imagesArr = [NSMutableArray array];
    for (NSString *name in arrays) {
    UIImage *image = [UIImage imageNamed:[(@"Loading.bundle") stringByAppendingPathComponent:name]];
    if (image) {
    [imagesArr addObject:image];
    }
    }
    return imagesArr;
    }
    
    - (void)viewDidLoad {
    [super viewDidLoad];
    
    UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:frame];
    gifImageView.animationImages = [self animationImages]; //获取Gif图片列表
    gifImageView.animationDuration = 5; //执行一次完整动画所需的时长
    gifImageView.animationRepeatCount = 0; //动画重复次数
    [gifImageView startAnimating];
    [self.view addSubview:gifImageView];
    }

    补充:可以直接取出动态image。需要吧图片设置进去。从零开始。

       

     UIImage *image = [UIImage animatedImageNamed:@"youhuiquanxiao" duration:2];

     


    3、使用SDWebImage

    但是很遗憾,SDWebImage 的 sd_setImageWithURL:placeholderImage:这个方法是不能播放本地Gif的,它只能显示Gif的第一张图片而已。So,此方法行不通

    // 行不通
    UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:frame]; [gifImageView sd_setImageWithURL:nil placeholderImage:[UIImage imageNamed:@"gifTest.gif"]];

    其实,在SDWebImage这个库里有一个UIImage+GIF的类别,里面为UIImage扩展了三个方法:

    @interface UIImage (GIF)
    + (IImage *)sd_animatedGIFNamed:(NSString *)name;
    + (UIImage *)sd_animatedGIFWithData:(NSData *)data;
    - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
    @end

    大家一看就知道,我们要获取处理后的Gif图片,其实只要调用前面两个中的其中一个方法就行了

    注意:第一个只需要传Gif的名字,而不需要带扩展名(如Gif图片名字为001@2x.gif,只需传001即可)


    我们就使用第二个方法试一试效果:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"gifTest" ofType:@"gif"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    UIImage *image = [UIImage sd_animatedGIFWithData:data];
    gifImageView.image = image;


    然后通过断点,我们发现:

    image的isa指针指向了_UIAnimatedImage ,说明它是一个叫作_UIAnimatedImage 的类(当然,这个_UIAnimatedImage 苹果是不会直接让我们使用的)

    _images 表示:这个Gif包含了多少张图片

    _duration表示:执行一次完整动画所需的时长

    其实,动画执续时间_duration也可以更改!
    我们来看下此方法的内部实现:

    + (UIImage *)sd_animatedGIFWithData:(NSData *)data {
    if (!data) {
    return nil;
    }
    
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    
    size_t count = CGImageSourceGetCount(source);
    
    UIImage *animatedImage;
    
    if (count <= 1) {
    animatedImage = [[UIImage alloc] initWithData:data];
    }
    else {
    NSMutableArray *images = [NSMutableArray array];
    
    NSTimeInterval duration = 0.0f;
    
    for (size_t i = 0; i < count; i++) {
    CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
    
    duration += [self sd_frameDurationAtIndex:i source:source];
    
    [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
    
    CGImageRelease(image);
    }
    
    if (!duration) {
    duration = (1.0f / 10.0f) * count;
    }
    
    animatedImage = [UIImage animatedImageWithImages:images duration:duration];
    }
    
    CFRelease(source);
    
    return animatedImage;
    }

    很明显,duration是可以随意更改的,只不过此方法设置了一个默认值 (duration = (1.0f / 10.0f) * count)

    归根到底,创建新的动态的Image其实是调用了系统提供的一个UIImage的类方法而已:

    UIImage *animatedImage = [UIImage animatedImageWithImages:images duration:duration];

    二、加载网络Gif文件

    加载网络的Gif文件就简单多了。最简单的方法,我们只需要使用SDWebImage 的 sd_setImageWithURL:这个方法传入Gif文件是url地址即可。
    纠其原因:稍微仔细看了SDWebImage内部实现就可以清楚,大概是以下几个步骤:

    1、SDWebImage根据url将Gif文件下载下来,格式为一个NSData
    2、如果判断是Gif格式,则会调用** sd_animatedGIFWithData:** 将Data转换成我们需要的Gif格式
    3、通过上面的方法二即可显示出Gif图片

    UIImage *image = [UIImage sd_animatedGIFWithData:data];
    gifImageView.image = image;


    总结

    一、加载本地Gif文件

    1、使用UIWebView不可以设置duration,其他两种方法都可设置。而且方法1的容器为UIWebView ,其余两种的容器都是大家熟悉的UIImageView
    2、方法2和方法3需要对应看应用场景

    如:下拉、上拉加载控件需要一个根据拉动距离设置特定的Image,则需要使用方法2

    直接显示Gif图片,则使用方法3会更方便

    二、加载网络Gif文件

    直接使用SDWebImage 的 sd_setImageWithURL:这个方法传入Gif文件是url地址即可

  • 相关阅读:
    Erlang 督程 启动和结束子进程
    cocos2d-x 3.0 内存管理机制
    c语言基本数据类型
    4星|《剑桥中国经济史:古代到19世纪》:经济学视角看中国古代史
    孟晚舟三种结局;共享单车大败局;失业潮不会来:4星|《财经》2018年第30期
    2018左其盛差评榜,罕见的差书榜
    2018左其盛好书榜,没见过更好的榜单
    罗振宇时间的朋友2018跨年演讲中最重要的35句话
    中国土地制度与房价走势相关9本书
    2星|水木然《世界在变软》:肤浅的朋友圈鸡汤文
  • 原文地址:https://www.cnblogs.com/weicyNo-1/p/7443652.html
Copyright © 2020-2023  润新知