SDWebImage源碼解讀之NSData+ImageContentType

NSData (ImageContentType)
很明顯這是一個(gè)NSData的分類(lèi),我們都知道分類(lèi)一般是用來(lái)擴(kuò)展一些方法的池磁。我們看看它擴(kuò)展了什么方法?

/**
*  Compute the content type for an image data
*
*  @param data the input data
*
*  @return the content type as string (i.e. image/jpeg, image/gif)
*/
  • (NSString *)sd_contentTypeForImageData:(NSData *)data;
    好,看這個(gè)方法码邻,就應(yīng)該明白了,目的是根據(jù)二進(jìn)制的數(shù)據(jù)獲取圖片的contentType另假。因此像屋,我們?cè)谶@里就要插入一段contentType的介紹了。

文件頭
文件頭是位于文件開(kāi)頭的一段承擔(dān)一定任務(wù)的數(shù)據(jù)边篮,一般都在開(kāi)頭的部分己莺。

別看這個(gè)文件頭和C語(yǔ)言中的頭文件讀起來(lái)很像,但這兩個(gè)東西其實(shí)根本沒(méi)有一點(diǎn)關(guān)系:頭文件是一種包含功能函數(shù),數(shù)據(jù)接口聲明的載體文件;而文件頭則是直接位于文件中的一段數(shù)據(jù),是文件的一部分

說(shuō)的簡(jiǎn)單一點(diǎn)就是,當(dāng)文件都使用二進(jìn)制流作為傳輸時(shí)戈轿,需要制定一套規(guī)范凌受,用來(lái)區(qū)分該文件到底是什么類(lèi)型的。 文件頭有很多個(gè)思杯,我們?cè)谶@里就介紹一些主流的且跟圖片相關(guān)的文件頭胜蛉。

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

可以看出來(lái)我們通過(guò)每個(gè)文件頭的第一個(gè)字節(jié)就能判斷出是什么類(lèi)型。但是值得注意的是52開(kāi)頭的解虱。這個(gè)要做特別的判斷攘须。

WebP這種格式很特別。是由12個(gè)字節(jié)組成的文件頭殴泰,我們?nèi)绻堰@些字節(jié)通過(guò)ASCII編碼后會(huì)得到下邊這樣一張表格:

+ (NSString *)sd_contentTypeForImageData:(NSData *)data {
    uint8_t c;
    [data getBytes:&c length:1];
    switch (c) {
        case 0xFF:
            return @"image/jpeg";
        case 0x89:
            return @"image/png";
        case 0x47:
            return @"image/gif";
        case 0x49:
        case 0x4D:
            return @"image/tiff";
        case 0x52:
            // R as RIFF for WEBP
            if ([data length] < 12) {
                return nil;
            }

            NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
            if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
                return @"image/webp";
            }

            return nil;
    }
    return nil;
}

現(xiàn)在再看上邊方法的實(shí)現(xiàn)于宙,我們就明白了。其中jpeg/png/gif/tiff 是最好判斷的悍汛。當(dāng)?shù)谝粋€(gè)字節(jié)為52時(shí)捞魁,如果長(zhǎng)度<12 我們就認(rèn)定為不是圖片。因此返回nil离咐。我們通過(guò)數(shù)據(jù)截取后獲得testString,如果testString頭部包含RIFF且尾部也包含WEBP谱俭,那么就認(rèn)定該圖片格式為webp。

演示
為了更好的演示webp,我們用代碼打印出結(jié)果來(lái)看看宵蛀。

首先我們獲得一個(gè)webp圖片:google@2x.webp

NSString *path = [[NSBundle mainBundle] pathForResource:@"google@2x" ofType:@"webp"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSString *contentType = [NSData sd_contentTypeForImageData:data];
NSLog(@"-----%@------%@", contentType, data);

我們看下打印結(jié)果:

-----image/webp------<52494646 72370000 57454250 56503858 0a000000 10000000 190200bd 0000414c 50484711 00000187 40906d33 83cd9ff7 778888a4 b3e53068 db4650c2 9f747a77 ff1822fa 9f927ff8 9224460e c3301c46 86216224 932431e6 1f5edfb6 6dd76d6c db56c195 20884bfb ffaf959d c214d01a 39e6f521 a2ffe95b b6edbaad 6ddb2a20 c03b40e4 ffffdade fbb0500b 2ddb2146 8c8788fe a7feff26 7ecae76a 9f2e77a3 fd9ce513 3ffc8fdd a7d286ec b65aa2d3 b3f6c735 44ef3ad6 ac879cce 21fafd58 929e6eac 53ccce25 e9c33bb8 d779b52f 438ccf59 9fdcc1bd ee7871ac f284be4f fad40eee 75c77b63 93b5d1ca 27de1de5 6c4376cf a28fece0 5e77bc36 3659b94a 64311e75 c8562dfa bc0eee75 c75b4393 efb32636 c3d165a7 167d5807 f7bae3a5 aecaf72b a1e28f21 1bb5e893 3ab8d71d 2f5da67c 9ba7472f 36d93892 3ea6a58e 30a6e39d 53e56b71

其中52494646 72370000 57454250正好占用了12字節(jié)昆著。那么也正好符合了我們上邊解釋的webp文件頭。

NSData (ImageContentTypeDeprecated)
這個(gè)分類(lèi)有一個(gè)東西值得我們學(xué)習(xí)术陶。

+ (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`");

這個(gè)__deprecated_msg可以告訴開(kāi)發(fā)者該方法不建議使用凑懂。這就有使用場(chǎng)景了。當(dāng)我們?cè)趯?xiě)框架或者類(lèi)的時(shí)候梧宫,如果功能相同接谨,但是想使用心得方法名的時(shí)候,使用__deprecated_msg給予其他開(kāi)發(fā)者一個(gè)提示塘匣。這遠(yuǎn)遠(yuǎn)比我們直接刪除舊的更專(zhuān)業(yè)脓豪。

轉(zhuǎn)載自:http://www.cnblogs.com/machao/p/6126826.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市忌卤,隨后出現(xiàn)的幾起案子扫夜,更是在濱河造成了極大的恐慌,老刑警劉巖埠巨,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件历谍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡辣垒,警方通過(guò)查閱死者的電腦和手機(jī)望侈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)勋桶,“玉大人脱衙,你說(shuō)我怎么就攤上這事侥猬。” “怎么了捐韩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵退唠,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我荤胁,道長(zhǎng)瞧预,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任仅政,我火速辦了婚禮垢油,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘圆丹。我一直安慰自己滩愁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布辫封。 她就那樣靜靜地躺著硝枉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪倦微。 梳的紋絲不亂的頭發(fā)上妻味,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音欣福,去河邊找鬼弧可。 笑死,一個(gè)胖子當(dāng)著我的面吹牛劣欢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裁良,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凿将,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了价脾?” 一聲冷哼從身側(cè)響起牧抵,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侨把,沒(méi)想到半個(gè)月后犀变,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秋柄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年获枝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骇笔。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡省店,死狀恐怖嚣崭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懦傍,我是刑警寧澤雹舀,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站粗俱,受9級(jí)特大地震影響说榆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寸认,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一签财、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧废麻,春花似錦荠卷、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至怜姿,卻和暖如春慎冤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沧卢。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工蚁堤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人但狭。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓披诗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親立磁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呈队,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容