天天看點

iOS 兩種加載GIF圖檔差別

現在開發不論是廣告頁,新手引導圖或者發送圖檔都有GIF了,但是很多時候不同的加載對記憶體也有不同的負擔

一般大家現在都用WKWebView或者SDWebImage,YYImage來加載比較對記憶體不會占用那麼多

例如我一般都是用WKWebView,不過聽說YYImage對gif圖播放支援比較好點,你有空可以試試那個。

 // 讀取gif圖檔資料

 NSData *gif = [NSDatadataWithContentsOfFile: [[NSBundlemainBundle] pathForResource:@"angelBird"ofType:@"gif"]];

 // webview生成

 WKWebView *webView = [[WKWebViewalloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width,self.view.frame.size.height)];

 [webView loadData:gifMIMEType:@"image/gif"characterEncodingName:nilbaseURL:nil];

 [self.viewaddSubview:webView];

另一種就是看着别人然後自己也寫了,原生的了,繼承ImageView

@interface RQimageView : UIImageView

-(void)yh_setImage:(NSURL *)imageUrl;

@end

#import "RQimageView.h"

#import <ImageIO/ImageIO.h>

@implementation RQimageView

-(void)getGifImageWithUrk:(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 = [[NSMutableArrayalloc]init];

    //存放每一幀播放的時間

    NSMutableArray * timeArray = [[NSMutableArrayalloc]init];

    //存放每張圖檔的寬度(一般在一個gif檔案中,所有圖檔尺寸都會一樣)

    NSMutableArray * widthArray = [[NSMutableArrayalloc]init];

    //存放每張圖檔的高度

    NSMutableArray * heightArray = [[NSMutableArrayalloc]init];

    //周遊

    for (size_t i=0; i<count; i++) {

        CGImageRef image =CGImageSourceCreateImageAtIndex(source, i,NULL);

        [imageArray addObject:(__bridgeUIImage *)(image)];

        CGImageRelease(image);

        //擷取圖檔資訊

        NSDictionary * info = (__bridgeNSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, i,NULL);

        CGFloat width = [[infoobjectForKey:(__bridgeNSString *)kCGImagePropertyPixelWidth]floatValue];

        CGFloat height = [[infoobjectForKey:(__bridgeNSString *)kCGImagePropertyPixelHeight]floatValue];

        [widthArray addObject:[NSNumbernumberWithFloat:width]];

        [heightArray addObject:[NSNumbernumberWithFloat:height]];

        NSDictionary * timeDic = [infoobjectForKey:(__bridgeNSString *)kCGImagePropertyGIFDictionary];

        CGFloat time = [[timeDicobjectForKey:(__bridgeNSString *)kCGImagePropertyGIFDelayTime]floatValue];

        allTime+=time;

        [timeArray addObject:[NSNumbernumberWithFloat:time]];

        CFRelease((__bridgeCFTypeRef)(info));

    }

    CFRelease(source);

    dataBlock(imageArray,timeArray,allTime,widthArray,heightArray);

}

-(void)yh_setImage:(NSURL *)imageUrl{

    __weakid __self = self;

    [selfgetGifImageWithUrk:imageUrlreturnData:^(NSArray<UIImage *> *imageArray,NSArray<NSNumber *> *timeArray,CGFloat totalTime, NSArray<NSNumber *> *widths,NSArray<NSNumber *> *heights) {

        //添加幀動畫

        CAKeyframeAnimation *animation = [CAKeyframeAnimationanimationWithKeyPath:@"contents"];

        NSMutableArray * times = [[NSMutableArrayalloc]init];

        float currentTime =0;

        //設定每一幀的時間占比

        for (int i=0; i<imageArray.count; i++) {

            [times addObject:[NSNumbernumberWithFloat:currentTime/totalTime]];

            currentTime+=[timeArray[i] floatValue];

        }

        [animation setKeyTimes:times];

        [animation setValues:imageArray];

        [animation setTimingFunction:[CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionLinear]];

        //設定循環

        animation.repeatCount=MAXFLOAT;

        //設定播放總時長

        animation.duration = totalTime;

        //Layer層添加

        [[(UIImageView *)__selflayer]addAnimation:animationforKey:@"gifAnimation"];

    }];

}

@end

調用

   NSURL * url = [[NSURLalloc]initFileURLWithPath:[[NSBundlemainBundle] pathForResource:@"angelBird.gif"ofType:nil]];

    RQimageView *imgView = [[RQimageViewalloc]initWithFrame:CGRectMake(0,0, self.view.frame.size.width,self.view.frame.size.height)];

    [imgView yh_setImage:url];

    [self.viewaddSubview:imgView];

我開發的時候對着兩種做過比較,開始覺得自己寫了用特别有成就感,然後發現用第二種記憶體飙到103MB

iOS 兩種加載GIF圖檔差別

然而用WKwebView還好,才11MB左右,原因你看代碼也知道啦,這樣循環加載播放,不彪才怪,哈哈