该文章阅读的SDWebImage的版本为4.3.3。
从这个分类的名字我们就能猜到这个类的作用是通过图片的二进制数据获取图片类型。
typedef NS_ENUM(NSInteger, SDImageFormat) { SDImageFormatUndefined = -1, SDImageFormatJPEG = 0, SDImageFormatPNG, SDImageFormatGIF, SDImageFormatTIFF, SDImageFormatWebP, SDImageFormatHEIC};复制代码
这个枚举定义了图片格式。
/** 通过图片的二进制数据判断图片的格式 */+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;复制代码
+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data { if (!data) { // 如果未传入二级制数据就返回“未定义类型” return SDImageFormatUndefined; } // 获取图片二级制数据的第一个字节,也就是八个比特 uint8_t c; [data getBytes:&c length:1]; switch (c) { // 根据字节的不同返回不同的类型 case 0xFF: return SDImageFormatJPEG; case 0x89: return SDImageFormatPNG; case 0x47: return SDImageFormatGIF; case 0x49: case 0x4D: return SDImageFormatTIFF; case 0x52: { // WebP格式的判断要复杂些:首先图片二级制的长度要超过12个字节,并且开头的12个字节通过ASCII编码后的字符串要以“RIFF”开头,并且以“WEBP”结束。 if (data.length >= 12) { //RIFF....WEBP NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { return SDImageFormatWebP; } } break; } case 0x00: { // HEIC格式的图片判断也比其他的要复杂些:首先图片二级制的长度也要超过12个字节,然后从第四个字节开始取八个字节并通过ASCII编码转换成字符串,如果字符串中包含“ftypheic”、“ftypheix”、“ftyphevc”和“ftyphevx”中的任意一个字符串就可以 if (data.length >= 12) { //....ftypheic ....ftypheix ....ftyphevc ....ftyphevx NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; if ([testString isEqualToString:@"ftypheic"] || [testString isEqualToString:@"ftypheix"] || [testString isEqualToString:@"ftyphevc"] || [testString isEqualToString:@"ftyphevx"]) { return SDImageFormatHEIC; } } break; } } // 如果没有满足上面的任何一种情况就返回“未定义类型” return SDImageFormatUndefined;}复制代码
// Currently Image/IO does not support WebP#define kSDUTTypeWebP ((__bridge CFStringRef)@"public.webp")// AVFileTypeHEIC is defined in AVFoundation via iOS 11, we use this without import AVFoundation#define kSDUTTypeHEIC ((__bridge CFStringRef)@"public.heic")复制代码
- 因为现在苹果还不支持WebP格式的图片,所以自定义一个WebP格式的标识。
- HEIC格式是iOS11以后才出现的,所以为了兼容之前的系统,也是自定义一个HEIC格式的标识
/** 将指定的图片格式转换成格式标识 */+ (nonnull CFStringRef)sd_UTTypeFromSDImageFormat:(SDImageFormat)format;复制代码
+ (nonnull CFStringRef)sd_UTTypeFromSDImageFormat:(SDImageFormat)format { CFStringRef UTType; switch (format) { // 根据传入的枚举类型,返回对应的格式标识 case SDImageFormatJPEG: UTType = kUTTypeJPEG; break; case SDImageFormatPNG: UTType = kUTTypePNG; break; case SDImageFormatGIF: UTType = kUTTypeGIF; break; case SDImageFormatTIFF: UTType = kUTTypeTIFF; break; case SDImageFormatWebP: UTType = kSDUTTypeWebP; break; case SDImageFormatHEIC: UTType = kSDUTTypeHEIC; break; default: // 默认的png类型 UTType = kUTTypePNG; break; } return UTType;}复制代码
可以发现这个分类内容简短明了,和我们在开头猜测的一致,这就是个判断图片类型的分类。
源码阅读系列:SDWebImage