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