iOS中直接使用Gif图片

今天有两个朋友问我如何直接在iOS中使用GIF图片,查了下咱们的度娘看到了简单的方法就是直接使用webView来加载。webView的好处在于每个subFrame之间的delay可以按照图片的设定显示出来。

还有个办法就是使用定时器模拟帧数,使用imageIO流来读取GIF的data。


我也尝试写个Demo来显示Gif

在demo中首先先分解出GIF的每个image,之后使用UIView动画来重现效果,在这个中使用了1/100秒作为一针

主体代码如下:

- (void)loadImageData {
    // 将所有的子帧动画加入数组
    NSMutableArray *array = [[NSMutableArray alloc] init];
    for (int i = 0; i < [GIF_frames count]; i++)
    {
        [array addObject: [self getFrameAsImageAtIndex:i]];
    }
    
    NSMutableArray *overlayArray = [[NSMutableArray alloc] init];
    UIImage *firstImage = [array objectAtIndex:0];
    CGSize size = firstImage.size;
    CGRect rect = CGRectZero;
    rect.size = size;
    
    //获取当前的上下文
    UIGraphicsBeginImageContext(size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    int i = 0;
    AnimatedGifFrame *lastFrame = nil;
    for (UIImage *image in array)
    {
        // 获取
        AnimatedGifFrame *frame = [GIF_frames objectAtIndex:i];
        
        //当前的展示
        UIImage *previousCanvas = nil;
        
        //将当前图形状态推入堆栈
        CGContextSaveGState(ctx);
        // 缩放比例(上下文,x的比例,y的比例(需使用负值),因为cgcontext的原点与uiview不同)
        CGContextScaleCTM(ctx, 1.0, -1.0);
        CGContextTranslateCTM(ctx, 0.0, -size.height);
        
        // 显示的大小
        CGRect clipRect;
        
        // 判断是哪种显示方法
        switch (frame.disposalMethod)
        {
            case 1: // 是否超边了
                // 显示的大小
                clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height);
                
                CGContextClipToRect(ctx, clipRect);
                break;
            case 2:
                clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height);
            
                CGContextClipToRect(ctx, clipRect);
                break;
            case 3:
                // 获取画板
                previousCanvas = UIGraphicsGetImageFromCurrentImageContext();
                
           
                clipRect = CGRectMake(frame.area.origin.x, size.height - frame.area.size.height - frame.area.origin.y, frame.area.size.width, frame.area.size.height);
                // Clip Context
                CGContextClipToRect(ctx, clipRect);
                break;
        }
        
        // 绘制实际图片实际大小
        CGContextDrawImage(ctx, rect, image.CGImage);
        // 重新渲染
        CGContextRestoreGState(ctx);
        
        //延迟时间要大于等于0
        if (frame.delay <= 0) {
            frame.delay = 10;
        }
        [overlayArray addObject:UIGraphicsGetImageFromCurrentImageContext()];
        
        // 设置最后显示大小
        lastFrame = frame;
        
        //
        switch (frame.disposalMethod)
        {
            case 2:
                CGContextSaveGState(ctx);
               
                CGContextScaleCTM(ctx, 1.0, -1.0);
                CGContextTranslateCTM(ctx, 0.0, -size.height);
                // 清除上下文
                CGContextClearRect(ctx, clipRect);
                // 重设上下文
                CGContextRestoreGState(ctx);
                break;
            case 3:
                CGContextSaveGState(ctx);
                
                CGContextScaleCTM(ctx, 1.0, -1.0);
                CGContextTranslateCTM(ctx, 0.0, -size.height);
              
                CGContextClearRect(ctx, lastFrame.area);
                
                CGContextDrawImage(ctx, rect, previousCanvas.CGImage);
               
                CGContextRestoreGState(ctx);
                break;
        }
        
       
        i++;
    }
    UIGraphicsEndImageContext();
    
    [self setImage:[overlayArray objectAtIndex:0]];
    [self setAnimationImages:overlayArray];
    
   
    
  //gif总共播放时间
    double total = 0;
    for (AnimatedGifFrame *frame in GIF_frames) {
        total += frame.delay;
    }
    
    // gif的针数大概为1/100一秒
    // UIImage来播放
    [self setAnimationDuration:total/100];
    
    // 设置是否循环
    [self setAnimationRepeatCount:0];
    
    [self startAnimating];
}


github位置: 点击打开链接

里面使用了很多c语言,主要就是拿来判断是否为gif,和解析gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值