1. 程式人生 > >SDWebImage源碼閱讀(十三)UIImage+MultiFormat

SDWebImage源碼閱讀(十三)UIImage+MultiFormat

with nsdata nslog geo bridge format ini cer available

  這個 UIImage 的一個叫 MultiFormat 的分類,看名字可能已經猜到,UIImage 的多版本,主要功能是用來做 NSData 和 UIImage 的相互轉化的。

  .h

1 + (nullable UIImage *)sd_imageWithData:(nullable NSData *)data;
2 - (nullable NSData *)sd_imageData;
3 - (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat;

  定義了 3 個方法,基本只是看方法名和返回值,已經基本猜到各個方法要實現的功能。

  1.這是一個類方法,一個NSData 對象做參數,轉化為一個 UIImage 對象返回。

  2.這是一個實例方法,把調取該方法的 UIImage 對象的 NSData 數據返回。

  3.獲取 UIImage 的指定圖片類型的 NSData 數據。

  .m

 1 + (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {
 2     if (!data) {
 3         return nil;
 4     }
 5     
 6     UIImage *image;
 7     SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:data];
8 if (imageFormat == SDImageFormatGIF) { 9 image = [UIImage sd_animatedGIFWithData:data]; 10 } 11 #ifdef SD_WEBP 12 else if (imageFormat == SDImageFormatWebP) 13 { 14 image = [UIImage sd_imageWithWebPData:data]; 15 } 16 #endif 17 else { 18 image = [[UIImage alloc] initWithData:data];
19 #if SD_UIKIT || SD_WATCH 20 UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data]; 21 if (orientation != UIImageOrientationUp) { 22 image = [UIImage imageWithCGImage:image.CGImage 23 scale:image.scale 24 orientation:orientation]; 25 } 26 #endif 27 } 28 29 30 return image; 31 }

  把 NSData 轉化為 UIImage。

  如果 data 不存在,則直接返回 nil。

  根據 data 判斷 UIImage 的後綴類型並賦值給 imageFormat。

  如果 imageFormat 是 SDImageFormatGIF,調用 sd_animatedGIFWithData: 把 data 轉化為圖片。

  如果 imageFormat 是 SDImageFormatWebP 則做相應的處理,這裏並沒有給出。

  其他的情況:

  直接調用 initWithData: 把 data 轉化為 UIImage。

  如果是 iOS 平臺開發或者 TV 平臺開發或者 WATCH 平臺開發,使用 data 調用 sd_imageOrientationFromImageData: 獲取圖片的方向並賦值給 orientation。

  如果 orientation 不等於 UIImageOrientationUP (默認方向),則調用:

1 + (UIImage *)imageWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(UIImageOrientation)orientation NS_AVAILABLE_IOS(4_0);

  重新調整圖片方向。

  最後返回 iamge。

 1 +(UIImageOrientation)sd_imageOrientationFromImageData:(nonnull NSData *)imageData {
 2     UIImageOrientation result = UIImageOrientationUp;
 3     CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
 4     if (imageSource) {
 5         CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
 6         if (properties) {
 7             CFTypeRef val;
 8             int exifOrientation;
 9             val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);
10             if (val) {
11                 CFNumberGetValue(val, kCFNumberIntType, &exifOrientation);
12                 result = [self sd_exifOrientationToiOSOrientation:exifOrientation];
13             } // else - if it‘s not set it remains at up
14             CFRelease((CFTypeRef) properties);
15         } else {
16             //NSLog(@"NO PROPERTIES, FAIL");
17         }
18         CFRelease(imageSource);
19     }
20     return result;
21 }

SDWebImage源碼閱讀(十三)UIImage+MultiFormat