1. 程式人生 > 其它 >iOS 載入本地Gif圖片

iOS 載入本地Gif圖片

技術標籤:iosobjective-cios

記錄一個iOS 載入本地gif格式圖片的方法


專案中需要載入本地gif圖片,一開始使用的是SDWebImage框架的

  • (nullable UIImage *)sd_imageWithGIFData:(nullable NSData *)data;

但是在部分機型上出現了gif不能正常顯示的問題(這裡是iPhone 6s,iOS 12.4), 然後更換載入方式,使用騰訊的QMUIKit框架進行載入,使用方法

  • (UIImage *)qmui_animatedImageWithData:(NSData *)data scale:(CGFloat)scale

發現還是無法正常顯示, 於是查看了qmui_animatedImageWithData:(NSData *)data scale:(CGFloat)scale的實現原始碼

  • (UIImage *)qmui_animatedImageWithData:(NSData *)data scale:(CGFloat)scale {
    // http://www.jianshu.com/p/767af9c690a3
    // https://github.com/rs/SDWebImage
    if (!data) {
    return nil;
    }
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    size_t count = CGImageSourceGetCount(source);
    UIImage *animatedImage = nil;
    if (count <= 1) {
    animatedImage = [[UIImage alloc] initWithData:data];
    } else {
    NSMutableArray<UIImage *> *images = [[NSMutableArray alloc] init];
    NSTimeInterval duration = 0.0f;
    for (size_t i = 0; i < count; i++) {
    CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
    duration += [self qmui_frameDurationAtIndex:i source:source];
    UIImage *frameImage = [UIImage imageWithCGImage:image scale:scale == 0 ? ScreenScale : scale orientation:UIImageOrientationUp];
    [images addObject:frameImage];
    CGImageRelease(image);
    }
    if (!duration) {
    duration = (1.0f / 10.0f) * count;
    }
    animatedImage = [UIImage animatedImageWithImages:images duration:duration];
    }
    CFRelease(source);
    return animatedImage;
    }

查看了註釋中的簡書和github,最後採用如下方式載入

// #import "UIImageView+Gif.h" //給imageView新增category

- (void)at_setGifImageWithGifFile:(NSString *)file animationDuration: (CGFloat)duration{
    
    NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:file withExtension: @"gif"]; //載入GIF圖片
    CGImageSourceRef gifSource = CGImageSourceCreateWithURL((CFURLRef) fileUrl, NULL);           //將GIF圖片轉換成對應的圖片源
    size_t frameCout = CGImageSourceGetCount(gifSource);                                         //獲取其中圖片源個數,即由多少幀圖片組成
    NSMutableArray *frames = [[NSMutableArray alloc] init];                                    //定義陣列儲存拆分出來的圖片
    for (size_t i = 0; i < frameCout; i++) {
        CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL); //從GIF圖片中取出源圖片
        UIImage *imageName = [UIImage imageWithCGImage:imageRef];                  //將圖片源轉換成UIimageView能使用的圖片源
        [frames addObject:imageName];                                              //將圖片加入陣列中
        CGImageRelease(imageRef);
    }
    CFRelease(gifSource);

    self.animationImages = frames; //將圖片陣列加入UIImageView動畫陣列中
    self.animationDuration = duration; //每完成一次動畫時長
    [self startAnimating];         //開啟動畫
    
}

這樣使用在UITableView或者UICollection等列表中載入可能會出現問題,可嘗試以下方法解決

if (!<#imageView#>.isAnimating) {
   [<#imageView#> startAnimating];
}

參考文件:
簡書github