1. 程式人生 > >圖片編碼簡介

圖片編碼簡介

參考文獻 nsdata jpg 二進制流 undefined ffd str int -1

數據在網絡中是以二進制流的形式傳播的,那麽我們該如何把那些1和0解析成我們需要的數據格式呢?當文件都使用二進制流作為傳輸時,需要制定一套規範,用來區分該文件到底是什麽類型的。 文件頭有很多個,我們在這裏就介紹一些主流的且跟圖片相關的文件頭。

JPEG (jpg),文件頭:FFD8FFE1
PNG (png),文件頭:89504E47
GIF (gif),文件頭:47494638
TIFF tif;tiff 0x49492A00
TIFF tif;tiff 0x4D4D002A
RAR Archive (rar),文件頭:52617221
WebP : 524946462A73010057454250 

可以看出來我們通過每個文件頭的第一個字節就能判斷出是什麽類型。但是值得註意的是52開頭的。這個要做特別的判斷。

我們如何獲取NSData中的第一個字節呢?如下:

 uint8_t c;
[data getBytes:&c length:1];

代碼實現如下:

1.定義圖片類型的type值
typedef NS_ENUM(NSInteger, SDImageFormat) {
    SDImageFormatUndefined = -1,
    SDImageFormatJPEG = 0,
    SDImageFormatPNG,
    SDImageFormatGIF,
    SDImageFormatTIFF,
    SDImageFormatWebP
};

2.代碼實現

+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data {
    if (!data) {
        return SDImageFormatUndefined;
    }
    
    //獲得NSData中的第一個字節
    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:
            // R as RIFF for WEBP
            if (data.length < 12) {
                return SDImageFormatUndefined;
            }
            
            NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
            if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
                return SDImageFormatWebP;
            }
    }
    return SDImageFormatUndefined;
}

參考文獻:SDWebImage 以及http://www.jianshu.com/p/471469ad9af1

圖片編碼簡介