Kingfisher源碼解析系列赦役,由于水平有限嚷量,哪里有錯(cuò)镇饮,肯請(qǐng)不吝賜教
- Kingfisher源碼解析之使用
- Kingfisher源碼解析之Options解釋
- Kingfisher源碼解析之加載流程
- Kingfisher源碼解析之加載動(dòng)圖
- Kingfisher源碼解析之ImageCache
- Kingfisher源碼解析之Processor和CacheSerializer
- Kingfisher源碼解析之ImagePrefetcher
本篇文章主要介紹Processor和CacheSerializer的基本定義和調(diào)用時(shí)機(jī)取逾,以及利用二者擴(kuò)展Kingfisher以支持webp格式的圖片
Processor
Processor介紹
Kingfisher中Processor是一個(gè)協(xié)議耗绿,定義了對(duì)原始數(shù)據(jù)進(jìn)行加工處理轉(zhuǎn)換成UIImage的能力(Kingfisher緩存的是處理成功之后的UIImage,根據(jù)options的值來決定是否緩存原始數(shù)據(jù))砾隅。
這里的原始數(shù)據(jù)是指ImageProcessItem误阻,它是一個(gè)枚舉類型。Processor和ImageProcessItem定義如下晴埂,都是特別簡單
public enum ImageProcessItem {
case image(KFCrossPlatformImage)
case data(Data)
}
public protocol ImageProcessor {
//標(biāo)識(shí)符究反,在緩存的時(shí)候用到,用于區(qū)分原始數(shù)據(jù)和處理加工之后的數(shù)據(jù)的
var identifier: String { get }
//交給具體的實(shí)現(xiàn)類去實(shí)現(xiàn)儒洛,ImageProcessItem精耐,最終返回一個(gè)UIImage
func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?
}
關(guān)于Processor的兩個(gè)問題
如果你了解過Kingfisher,請(qǐng)嘗試回答下這2個(gè)問題
- ImageProcessor.process都在什么時(shí)候調(diào)用呢琅锻?
- ImageProcessItem關(guān)聯(lián)了2種類型卦停,一種是Data,另一種是UIImage浅浮,那么這2種類型分別什么時(shí)候會(huì)用到呢?
ImageProcessor.process在什么時(shí)候調(diào)用捷枯,在調(diào)用的時(shí)候會(huì)傳遞什么類型的數(shù)據(jù)滚秩?
- 當(dāng)從網(wǎng)絡(luò)上下載圖片成功之后,會(huì)調(diào)用process把下載成功的data加工處理成我們需要的UIImage淮捆。很明顯這種情況下傳遞的是Data類型郁油。
- 當(dāng)source是ImageDataProvider時(shí),從source中獲取到Data之后攀痊,會(huì)調(diào)用process把data加工處理成我們需要的UIImage桐腌。很明顯這種情況下傳遞的也是Data類型。
- 當(dāng)讀取緩存失敗苟径,但讀取原始數(shù)據(jù)緩存成功之后案站,會(huì)調(diào)用process把原始數(shù)據(jù)加工處理成我們需要的UIImage。這種情況會(huì)先把讀取到的data使用cacheSerializer反序列化為UIImage棘街,然后傳遞UIImage類型
CacheSerializer
CacheSerializer介紹
Kingfisher中CacheSerializer定義了圖片序列化和反序列化的能力蟆盐,也是一個(gè)協(xié)議
public protocol CacheSerializer {
func data(with image: KFCrossPlatformImage, original: Data?) -> Data?
func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?
}
CacheSerializer的調(diào)用時(shí)機(jī)
- 當(dāng)需要磁盤緩存時(shí),會(huì)調(diào)用
func data(with image: KFCrossPlatformImage, original: Data?) -> Data?
把image序列化成data遭殉,以便寫入文件 - 當(dāng)從磁盤讀取數(shù)據(jù)時(shí)石挂,會(huì)調(diào)用
func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage?
把data反序列化為UIImage
使用Processor和CacheSerializer擴(kuò)展Kingfisher,使Kingfisher支持webP格式的圖片
Kingfisher本身是不支持webp格式的圖片险污,但是可以利用Processor和CacheSerializer對(duì)Kingfisher進(jìn)行擴(kuò)展痹愚,讓Kingfisher支持webP格式的圖片
WebP 標(biāo)準(zhǔn)是 Google 定制的,迄今為止也只有 Google 發(fā)布的 libwebp 實(shí)現(xiàn)了該的編解碼 。 所以這個(gè)庫也是該格式的事實(shí)標(biāo)準(zhǔn)拯腮。
因此要想支持webp格式的圖片窖式,需要依賴libwebp庫,用來實(shí)現(xiàn)圖片的編碼和解碼疾瓮,對(duì)于這塊的代碼我是從SDWebImageWebPCoder復(fù)制過來的脖镀,并且去掉了對(duì)動(dòng)圖的支持和一些SD配置的代碼,如果你對(duì)這塊感興趣狼电,請(qǐng)參考源碼蜒灰,由于SD是OC寫的,所以這部分我用的也是OC肩碟,最終給UIImage添加了一個(gè)分類强窖,提供了下面2個(gè)方法
@interface UIImage (WebP)
//序列化為Data
@property(nonatomic,strong,readonly,nullable) NSData *webPData;
//通過data反序列化為UIImage
+ (nullable instancetype)imageWithWebPData:(NSData *)webPdata;
+
@end
實(shí)現(xiàn)Processor
在process判斷item的類型,若是image則直接返回削祈,若是data則反序列化為UIImage
public struct WebPProcessor: ImageProcessor {
public static let `default` = WebPProcessor()
public let identifier = "WebPProcessor"
public init() {}
public func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
switch item {
case .image(let image):
return image
case .data(let data):
return UIImage(webPData: data)
}
}
}
CacheSerializer
public struct WebPCacheSerializer: CacheSerializer {
public static let `default` = WebPCacheSerializer()
private init() {}
public func data(with image: KFCrossPlatformImage, original: Data?) -> Data? {
return image.webPData;
}
public func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
return UIImage(webPData: data);
}
}
使用
if let url = URL(string:"http://q21556z4z.bkt.clouddn.com/123.webp?e=1575537931&token=7n8bncOpnUSrN4mijeEAJRdVXnC-jm-mk5qTjKjR:L1_MWy3xugv9ct6PD294CHzwiSE=&attname=") {
imageView.kf.setImage(
with: url,
options: [.processor(WebPProcessor.default), .cacheSerializer(WebPCacheSerializer.default)]
)
}
補(bǔ)充
雖說上面的代碼都比較簡單翅溺,但是我感覺Kingfisher的這個(gè)設(shè)計(jì)真的挺好的,可擴(kuò)展支持任意類型的圖片髓抑,并且Processor是用來加工處理圖片的咙崎,能做的還有其他方面,比如Kingfisher中提供了多種實(shí)現(xiàn)類吨拍,比如圓角的RoundCornerImageProcessor褪猛,顯示高清圖的DownsamplingImageProcessor,組裝多種Processor的GeneralProcessor羹饰。
demo地址