美文网首页
SDWebImage扩展-图像处理

SDWebImage扩展-图像处理

作者: youlianchun | 来源:发表于2017-09-13 15:21 被阅读0次

SDWebImage 大家都用过,加载网络图片的一个类库,非常好用,可是在一些比较特殊的情况下就会出现一些不足,如下情况:
app 很多地方的网络图片都需要在显示时候进行描边处理或者圆角处理(直接设置layer圆角,多了会导致table卡顿,所以通常是在图片上做手脚),而图片的加载显示刚好用的SDWebImage,这时候问题就来了,SDWebImage缓存的图片是原图,每次在显示时候对图片进行加工然后显示,其实是很糟糕的做法,完全可以在缓存图片前处理好,显示时候直接拿来用。
这里介绍的就是未处理这个功能,新版不知道是不是支持这种情况。
怎么搞呢,分析源码吧,网上很多介绍很详细的文章,我这边简单说一下:
关键函数如下图:


下载函数

这个函数是获取一手图片文件的地方,代码还有点多


原始数据

做法很简单,就是在这个方法的这个block 获取到图片时候用另外一个block把图片传到调用的地方,加工后再返回回来,缓存这个新图片,如图:


图片处理替换

这样基本达满足前边描述的情况了,
但是如果这一张图片在多个地方使用,而且这些个地方对图片的处理有事不一样的时候就不行了,比方有的描边有的圆角。
怎么办呢,
在设置图片的地方再加个参数key来标记图片处理操作类型
这个处理起来比较简单,只需要搞一下原本缓存的key就可以了,原本是酱紫的:


缓存key

搞成酱紫就可以了:


新缓存key

然后设置函数把两个新的参数补上去救ok了,为了不影响原来的结构,新建了一个分类,新增了这么个下载函数如下图:


新函数

然后扩展一下设置图片的方法就完美了如下:

- (void)sd_setImageWithURL:(NSURL *)url processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock {
    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil processKey:processKey processBlock:processBlock];
}

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil processKey:processKey processBlock:processBlock] ;
}

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil processKey:processKey processBlock:processBlock];
}

- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock processKey:processKey processBlock:processBlock];
}

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock processKey:processKey processBlock:processBlock];
}

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock{
    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock processKey:processKey processBlock:processBlock];
}

设置函数里的总入口改一下

- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock processKey:(NSString*)processKey processBlock:(SDWebImageProcessBlock)processBlock {
    [self sd_cancelCurrentImageLoad];
    objc_setAssociatedObject(self, &imageURLKey_Process, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    if (!(options & SDWebImageDelayPlaceholder)) {
        dispatch_main_async_safe(^{
            self.image = placeholder;
        });
    }
    
    if (url) {
        
        // check if activityView is enabled or not
        if ([self showActivityIndicatorView]) {
            [self addActivityIndicator];
        }
        
        __weak __typeof(self)wself = self;
        id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
            [wself removeActivityIndicator];
            if (!wself) return;
            dispatch_main_sync_safe(^{
                if (!wself) return;
                if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
                {
                    completedBlock(image, error, cacheType, url);
                    return;
                }
                else if (image) {
                    wself.image = image;
                    [wself setNeedsLayout];
                } else {
                    if ((options & SDWebImageDelayPlaceholder)) {
                        wself.image = placeholder;
                        [wself setNeedsLayout];
                    }
                }
                if (completedBlock && finished) {
                    completedBlock(image, error, cacheType, url);
                }
            });
        } processKey:processKey processBlock:processBlock];
        [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
    } else {
        dispatch_main_async_safe(^{
            [self removeActivityIndicator];
            if (completedBlock) {
                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
                completedBlock(nil, error, SDImageCacheTypeNone, url);
            }
        });
    }
}

然后声明一下头文件就好了,
.m文件遇到一些属性找不到弄个延展引进来就好了如下:


属性引入

有点多,为了方便,没办法,人家本来就这么多,oc下只能一个个搞。
这么一来就可以完美满足前边描述的情况了。

ps:SDWebImage 版本 3.8.2,后边的情况不知道如何,就还没更新。

相关文章

网友评论

      本文标题:SDWebImage扩展-图像处理

      本文链接:https://www.haomeiwen.com/subject/juaksxtx.html