IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    iOS学习 – 23 ImageIO 播放 GIF

    summer发表于 2016-11-09 06:09:17
    love 0

    一、给原生的 UIImageView 添加类别来支持 GIF 播放

    GIF 动态图片文件中包含了一组图片及信息,信息主要记录着每一帧图片播放的时间,我们如果获取到了 gif 文件中所有的图片同时又获取到每一帧图片播放的时间,就可以为 UIImageView 添加关键帧动画的方法让其播放 GIF 的内容了

    1.新建一个 UIImageView 的类别

    2.解析 GIF ,获得 GIF 的信息

    #pragma mark -- 解析 DGIF
    -(void)gifWithUrl:(NSURL *)url
    returnData:(
    void(^)(NSArray<UIImage *> * imageArray,
    NSArray
    <NSNumber *>*timeArray,
    CGFloat totalTime,
    NSArray
    <NSNumber *>* widths,
    NSArray
    <NSNumber *>* heights))dataBlock
    {
    //通过文件的 url 来将 gif 文件读取为图片数据引用
    CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url,NULL);
    //获取 gif 文件中的图片个数
    size_t count = CGImageSourceGetCount(source);
    //定义一个变量记录 gif 播放一轮的时间
    float allTime = 0;
    //存放所有图片
    NSMutableArray *imageArray = [NSMutableArray array];
    //存放每一帧播放的时间
    NSMutableArray *timeArray = [NSMutableArray array];
    //存放每张图片的宽度(一般在一个 gif 文件中,所有文件的尺寸都一样)
    NSMutableArray *widthArray = [NSMutableArray array];
    //存放每张图片的高度
    NSMutableArray * heightArray = [NSMutableArray array];
    //遍历
    for(size_t i = 0;i < count; i++){
    //获取图片信息
    CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
    [imageArray addObject:(__bridge UIImage
    *)(image)];
    CGImageRelease(image);
    //获取图片信息
    NSDictionary *info = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, i, NULL);
    NSLog(
    @"%@",info);
    CGFloat width
    = [[info objectForKey:(__bridge NSString *)kCGImagePropertyPixelWidth]floatValue];
    CGFloat height
    = [[info objectForKey:(__bridge NSString *)kCGImagePropertyPixelHeight]floatValue];
    [widthArray addObject:[NSNumber numberWithFloat:width]];
    [heightArray addObject:[NSNumber numberWithFloat:height]];

    NSDictionary *timeDic = [info objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary];
    CGFloat time
    = [[timeDic objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime]floatValue];
    allTime
    += time;
    [timeArray addObject:[NSNumber numberWithFloat:time]];
    }
    dataBlock(imageArray,timeArray,allTime,widthArray,heightArray);
    }

    3.加载 GIF

    timingFunction: 控制动画运行的节奏
    • kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
    • kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
    • kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
    • kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为
    #pragma mark -- 加载 GIF
    - (void)cc_setImage:(NSURL *)imageUrl {
    __weak
    id _self = self;
    [self gifWithUrl:imageUrl returnData:
    ^(NSArray<UIImage *> *imageArray, NSArray<NSNumber *> *timeArray, CGFloat totalTime, NSArray<NSNumber *> *widths, NSArray<NSNumber *> *heights) {

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
    NSMutableArray
    * times = [[NSMutableArray alloc]init];
    float currentTime = 0;
    //设置每一帧的时间占比
    for (int i = 0; i < imageArray.count; i++) {
    [times addObject:[NSNumber numberWithFloat:currentTime
    /totalTime]];
    currentTime
    += [timeArray[i] floatValue];
    }
    [animation setKeyTimes:times];
    [animation setValues:imageArray];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    //设置循环
    animation.repeatCount= MAXFLOAT;
    //设置播放总时长
    animation.duration = totalTime;
    //Layer层添加
    [[(UIImageView *)_self layer]addAnimation:animation forKey:@"gifAnimation"];
    }];
    }

     



沪ICP备19023445号-2号
友情链接