關于iOS中Gif播放

最近看了一下Gif播放,因為iOS是沒有可以直接播放Gif資源的控件的,所以,這就需要我們想辦法了。。。

準備


通過上網Google,也查到了一些相關方法,下面列舉一下:

  • UIWebView播放
    NSString *path = [[NSBundle mainBundle] pathForResource:@"niconiconi" ofType:@"gif"];
    NSData *gifData = [NSData dataWithContentsOfFile:path];
    UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
    webView.scalesPageToFit = YES;
    [webView loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
    webView.backgroundColor = [UIColor clearColor];
    webView.opaque = NO;
    [self.view addSubview:webView];
  • 將GIF分解成多張PNG圖片,使用UIImageView播放
 // 需導入 #import <ImageIO/ImageIO.h> 

     NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"niconiconi" withExtension:@"gif"]; 
    // 將GIF圖片轉換成對應的圖片源
    CGImageSourceRef gifSource = CGImageSourceCreateWithURL((CFURLRef) fileUrl, NULL);           
    // 獲取圖片源個數,即由多少幀圖片組成
    size_t frameCout = CGImageSourceGetCount(gifSource);                                         
    NSMutableArray *frames = [[NSMutableArray alloc] init];                                      
    for (size_t i = 0; i < frameCout; i++) {
       // 從GIF圖片中取出源圖片
        CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL); 
        UIImage *imageName = [UIImage imageWithCGImage:imageRef];                  
        [frames addObject:imageName];                                              
        CGImageRelease(imageRef);
     }
    UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    gifImageView.animationImages = frames; 
    gifImageView.animationDuration = 0.1;
    [gifImageView startAnimating];    
    [self.view addSubview:gifImageView];
  • 使用 SDWebImage 播放NSData數據的GIF + (UIImage *)sd_animatedGIFWithData:(NSData *)data
    NSString  *filePath = [[NSBundle bundleWithPath:[[NSBundle mainBundle] bundlePath]] pathForResource:@"niconiconi" ofType:@"gif"];
    NSData  *imageData = [NSData dataWithContentsOfFile:filePath];
    UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    gifImageView.backgroundColor = [UIColor clearColor];
    gifImageView.image = [UIImage sd_animatedGIFWithData:imageData];
    [self.view addSubview:gifImageView];

FLAnimatedImage 使用

    NSURL *url = [[NSBundle mainBundle] URLForResource:@"niconiconi" withExtension:@"gif"];
    NSData *data = [NSData dataWithContentsOfURL:url];
    FLAnimatedImage *animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:data];
    FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
    imageView.animatedImage = image;
    imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
    [self.view addSubview:imageView];

YYImage 使用

    // YYImage可以加載包括gif,WebP,APNG等圖片
    YYImage * image = [YYImage imageNamed:@"niconiconi"];
    YYAnimatedImageView *imageView = [[YYAnimatedImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(0, 0, 300, 300);
    [self.view addSubview:imageView];
  • 對比總結

UIWebView實現播放Gif簡單直接,如果只想單純的播放一下建議使用此方法。弊端就是只能循環播放,無法控制它的暫停和其他操作, 不夠靈活。

UIImageView采用幀動畫將圖片一張張顯示,可以調節播放次數和速度但圖片過多過大內存會很有壓力。另外在保證播放的動畫清晰和時長的情況下Gif文件大小會遠小于多張PNG圖片的大小。

使用第三方播放Gif動畫可以對動畫進行一系列操作,暫停或者快進等操作,適合Gif文件比較大的情況下使用。

簡單應用


這里呢,我使用 FLAnimatedImage 第三方庫, 簡單實現了一個新特性引導動畫, 直接進行Gif播放,使用起來還算不錯 , 性能消耗也不是很大, 如下:

性能使用圖

實現原理也是很簡單,UIScrollView + FLAnimatedImageView 根據 contentOffset 控制當前頁數。

下面是幾個核心代碼:

// 設置初始顯示樣式
- (void)setupDefault {
    self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH * TOTALCOUNT, 0);
    for (int i = 0; i<TOTALCOUNT; i++) {
        FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
        FLAnimatedImage *image = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",i+1]];
        if (i == 0) {
            imageView.animatedImage = image;
        } else {
            // 設置首幀圖片
            imageView.image = image.posterImage;
        }
        imageView.frame = CGRectMake(SCREEN_WIDTH * i, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
        [_scrollView addSubview:imageView];
        [self.animatedImageViews addObject:imageView];
    }
    self.pageControl.numberOfPages = TOTALCOUNT;
}

// 根據Gif資源獲取FLAnimatedImage
- (FLAnimatedImage *)animatedImageWithURLForResource:(NSString *)fileName {
    NSURL *url = [[NSBundle mainBundle] URLForResource:fileName withExtension:@"gif"];
    NSData *data = [NSData dataWithContentsOfURL:url];
    FLAnimatedImage *animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:data];
    return animatedImage;
}

// 滑到當前顯示頁數
- (void)setupAnimateImage:(int)page {
    FLAnimatedImageView *imageView = self.animatedImageViews[page];
    FLAnimatedImage *image = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",page+1]];
    imageView.animatedImage = image;
    
    if (page == TOTALCOUNT - 1) {
        imageView.loopCompletionBlock= ^(NSUInteger loopCountRemaining) {
            [UIView animateWithDuration:0.3 animations:^{
                self.entryBtn.hidden = NO;
                self.entryBtnBottom.constant = 75;
                [self.entryBtn layoutIfNeeded];
            }];
        };
    } else {
        self.entryBtn.hidden = YES;
        self.entryBtnBottom.constant = 0;
        [self.entryBtn layoutIfNeeded];
    }
}

// 每次滑到當前頁確保從首幀播放
- (void)setupFistFrameImageWithPage:(int)page {
    // 設置首幀圖片,每次播放從首幀開始(如果不設置,滑回上一個會顯示最后一幀的圖片)
    if (self.lastPage != page) {
        if (self.lastPage < page ) {
            FLAnimatedImageView *imageView1 = self.animatedImageViews[page-1];
            imageView1.animatedImage = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",page]];
            imageView1.image = imageView1.animatedImage.posterImage;
        } else {
            FLAnimatedImageView *imageView2 = self.animatedImageViews[page+1];
            imageView2.animatedImage = [self animatedImageWithURLForResource:[NSString stringWithFormat:@"引導頁%d",page+2]];
            imageView2.image = imageView2.animatedImage.posterImage;
        }
    }
}

使用效果預覽 :

guide.gif

附上地址: https://github.com/ismilesky/GifPlay.git

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容