源码阅读:SDWebImage(三)——NSData+ImageContentType

该文章阅读的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

源码阅读:SDWebImage(一)——从使用入手

源码阅读:SDWebImage(二)——SDWebImageCompat

源码阅读:SDWebImage(三)——NSData+ImageContentType

源码阅读:SDWebImage(四)——SDWebImageCoder

源码阅读:SDWebImage(五)——SDWebImageFrame

源码阅读:SDWebImage(六)——SDWebImageCoderHelper

源码阅读:SDWebImage(七)——SDWebImageImageIOCoder

源码阅读:SDWebImage(八)——SDWebImageGIFCoder

源码阅读:SDWebImage(九)——SDWebImageCodersManager

源码阅读:SDWebImage(十)——SDImageCacheConfig

源码阅读:SDWebImage(十一)——SDImageCache

源码阅读:SDWebImage(十二)——SDWebImageDownloaderOperation

源码阅读:SDWebImage(十三)——SDWebImageDownloader

源码阅读:SDWebImage(十四)——SDWebImageManager

源码阅读:SDWebImage(十五)——SDWebImagePrefetcher

源码阅读:SDWebImage(十六)——SDWebImageTransition

源码阅读:SDWebImage(十七)——UIView+WebCacheOperation

源码阅读:SDWebImage(十八)——UIView+WebCache

源码阅读:SDWebImage(十九)——UIImage+ForceDecode/UIImage+GIF/UIImage+MultiFormat

源码阅读:SDWebImage(二十)——UIButton+WebCache

源码阅读:SDWebImage(二十一)——UIImageView+WebCache/UIImageView+HighlightedWebCache

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值