SDWebImage记录

2019-08-19  本文已影响0人  super_NTF

这是我第一个篇文章,后面希望自己能陆续记录自己遇到的小问题。

工作很多年了,我一直认为效率至上,所以一直都觉得记录是一件很浪费时间的事情。最近被一些事情触动,觉得记录是一个很好的习惯。现在开始养成也不晚。加油!!

下面进入正题!!!!!

###背景:

项目里图片库用的就是SD,最近想在图片缓存的过程中做些转码相关的工作。

于是写了下面的代码。

```

SDWebImageCacheSerializer *cs =

[SDWebImageCacheSerializer cacheSerializerWithBlock:

^NSData * _Nullable(

UIImage * _Nonnull image,

NSData * _Nullable data,

NSURL * _Nullable imageURL)

{

//中间不重要

    return  data;

}];

```

在整体方案中,我们做了开关,如果出现线上问题,以上代码会变成下面的样子。

```

SDWebImageCacheSerializer *cs =

[SDWebImageCacheSerializer cacheSerializerWithBlock:nil];

```

###问题描述:

把block设置成nil之后,下载到本地的gif图用电脑打开不能播放。

###问题定位:

SDImageCache.m 类中下面的方法

```

- (void)storeImage:(nullableUIImage*)image

        imageData:(nullableNSData*)imageData

            forKey:(nullableNSString*)key

          toMemory:(BOOL)toMemory

            toDisk:(BOOL)toDisk

        completion:(nullableSDWebImageNoParamsBlock)completionBlock

```

有如下代码:

```

  SDImageFormat format;

                    if ([SDImageCoderHelper CGImageContainsAlpha:image.CGImage]) {

                        format =SDImageFormatPNG;

                    }else{

                        format =SDImageFormatJPEG;

                    }

                    data = [[SDImageCodersManager sharedManager] encodedDataWithImage:image format:format options:nil];

```

###问题解答:

image.CGImage已经是解码之后的图片,通过判断图片是否有透明度,不管是啥图片都只存了两种类型,png、jpeg。

所以gif图片存成了png 就不能自动播放了。

###那图片gif图又是如何能正常播放的呢?

gif一定是有Alpha通道的(虽然不知道为什么)所以图片在存储的时候,存成了png图片。

下次启动图片解码的时候使用SDImageAPNGCoder这类解码,解码过程如下:

```

- (UIImage*)decodedImageWithData:(NSData*)data options:(nullableSDImageCoderOptions*)options {

。。。

    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);

    if(!source) {

        returnnil;

    }

    size_t count = CGImageSourceGetCount(source);

    UIImage*animatedImage;

    BOOLdecodeFirstFrame = [options[SDImageCoderDecodeFirstFrameOnly]boolValue];

    if(decodeFirstFrame || count <=1) {

        animatedImage = [[UIImagealloc]initWithData:datascale:scale];

    }else{

        NSMutableArray<SDImageFrame *> *frames = [NSMutableArray array];

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

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

            if(!imageRef) {

                continue;

            }

            floatduration = [selfsd_frameDurationAtIndex:isource:source];

            UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];

            CGImageRelease(imageRef);

            SDImageFrame *frame = [SDImageFrame frameWithImage:image duration:duration];

            [framesaddObject:frame];

        }

        NSUIntegerloopCount = [selfsd_imageLoopCountWithSource:source];

        animatedImage = [SDImageCoderHelper animatedImageWithFrames:frames];

        animatedImage.sd_imageLoopCount= loopCount;

    }

    animatedImage.sd_imageFormat = SDImageFormatPNG;

    CFRelease(source);

    return animatedImage;

}

```

综上,gif图又解码成了序列帧。

###那如果是webp图片会怎么样?

图片存储的时候,调用CacheSerializer的block,block直接返回nil。那硬盘缓存只能存储已经解码过的image。然后在进行判断当前图片是否有透明度,选择存储png或者jpg。下次从缓存读取图片的时候,读取的就是png或者jpg。所以webp图片也不会有问题。

ps:sd这考虑的还是非常全面的,不会到是方案设计带来的意外惊喜,还是有意为之,总之厉害的很。

上一篇 下一篇

猜你喜欢

热点阅读