</pre><pre code_snippet_id="1873833" snippet_file_name="blog_20160909_7_5498294" name="code" class="objc">
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 14px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); min-height: 16px;"><span style="font-variant-ligatures: no-common-ligatures"></span>
</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 14px; line-height: normal; font-family: Menlo;"><pre name="code" class="objc"><span style="color:#663300;">
static NSString *const kPngRangeValue = @"bytes=16-23";
static NSString *const kJpgRangeValue = @"bytes=0-209";//0-209
static NSString *const kGifRangeValue = @"bytes=6-9";
static NSString *const kHTMLJpgRangeValue = @"bytes=0-1103";//头信息包含HTML的jpg或者其他格式信息的JPG
typedef NS_ENUM(NSUInteger, ImageType) {
PngImage = 1,
JpgImage,
GifImage,
};
</span>
</pre><pre code_snippet_id="1873833" snippet_file_name="blog_20160909_5_2226671" name="code" class="objc">//同步下载图片的头信息
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URLString]];
if ([self.picUrl hasSuffix:@".png"]) {
[request setValue:kPngRangeValue forHTTPHeaderField:@"Range"];
self.type = PngImage;
}else if([self.picUrl hasSuffix:@".jpg"]){
[request setValue:kHTMLJpgRangeValue forHTTPHeaderField:@"Range"];
self.type = JpgImage;
}else if([self.picUrl hasSuffix:@".gif"]){
[request setValue:kGifRangeValue forHTTPHeaderField:@"Range"];
self.type = GifImage;
}
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
NSURLResponse *response = nil;
NSError *error = NULL;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
</pre><pre code_snippet_id="1873833" snippet_file_name="blog_20160909_8_1212133" name="code" class="objc"><p style="margin-top: 0px; margin-bottom: 0px; font-size: 14px; line-height: normal; font-family: Menlo;"><pre name="code" class="objc">switch (_type) {
case PngImage:
{
size = <span style="color:#ff6600;">pngImageSizeWithHeaderData(data)</span>;
NSLog(@"png image size : %@", NSStringFromCGSize(size));
}
break;
case JpgImage:
{
size = <span style="color:#ff6600;">jpgImageSizeWithHeaderData(data)</span>;
if (size.width == 0) {
size = [self againDownLoad];
}
NSLog(@"jpg image size : %@", NSStringFromCGSize(size));
}
break;
case GifImage:
{
size = <span style="color:#ff6600;">gifImageSizeWithHeaderData(data)</span>;
NSLog(@"gif image size : %@", NSStringFromCGSize(size));
}
break;
default:
break;
}
CGSize pngImageSizeWithHeaderData(NSData *data)
{
int w1 = 0, w2 = 0, w3 = 0, w4 = 0;
[data getBytes:&w1 range:NSMakeRange(0, 1)];
[data getBytes:&w2 range:NSMakeRange(1, 1)];
[data getBytes:&w3 range:NSMakeRange(2, 1)];
[data getBytes:&w4 range:NSMakeRange(3, 1)];
int w = (w1 << 24) + (w2 << 16) + (w3 << 8) + w4;
int h1 = 0, h2 = 0, h3 = 0, h4 = 0;
[data getBytes:&h1 range:NSMakeRange(4, 1)];
[data getBytes:&h2 range:NSMakeRange(5, 1)];
[data getBytes:&h3 range:NSMakeRange(6, 1)];
[data getBytes:&h4 range:NSMakeRange(7, 1)];
int h = (h1 << 24) + (h2 << 16) + (h3 << 8) + h4;
return CGSizeMake(w, h);
}
<span style="color:#cc66cc;">CGSize gifImageSizeWithHeaderData(NSData *data)
{
short w1 = 0, w2 = 0;
[data getBytes:&w1 range:NSMakeRange(1, 1)];
[data getBytes:&w2 range:NSMakeRange(0, 1)];
short w = (w1 << 8) + w2;
short h1 = 0, h2 = 0;
[data getBytes:&h1 range:NSMakeRange(3, 1)];
[data getBytes:&h2 range:NSMakeRange(2, 1)];
short h = (h1 << 8) + h2;
return CGSizeMake(w, h);
}</span>
<span style="color:#cc66cc;">CGSize jpgImageSizeWithHeaderData(NSData *data)
{
#ifdef DEBUG
// @"bytes=0-209"
// assert([data length] == 210);
#endif
short word = 0x0;
[data getBytes:&word range:NSMakeRange(0x15, 0x1)];
NSLog(@"short word == %d",word);
if (word == 0xdb) {
[data getBytes:&word range:NSMakeRange(0x5a, 0x1)];
if (word == 0xdb) {
// 两个DQT字段
NSData *exactData = [data subdataWithRange:NSMakeRange(0xa3, 0x4)];
return jpgImageSizeWithExactData(exactData);
} else {
// 一个DQT字段
NSData *exactData = [data subdataWithRange:NSMakeRange(0x5e, 0x4)];
return jpgImageSizeWithExactData(exactData);
}
} else {
NSUInteger len = [data length];
char * chars = (char *)[data bytes];
NSMutableString * hexString = [[NSMutableString alloc] init];
for(NSUInteger i = 0; i < len; i++ )
[hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]];
NSLog(@"二进制元数据%@",data);
NSLog(@"转换之后的二进制数据%@",hexString);
//寻找字节FFC0
NSRange range = [hexString rangeOfString:@"ffc0"];
if (range.location == NSNotFound) {</span>
<span style="color:#cc66cc;"><span style="white-space:pre"> </span> //可以继续去下载更多字节的图片信息
return CGSizeZero;
}
NSString *str = [hexString substringWithRange:NSMakeRange(range.location + range.length + 6, 8)];
NSLog(@"取出之后的值 === %@",[hexString substringWithRange:NSMakeRange(range.location + range.length + 6, 8)]);
//将字符串变成16进制
NSData *bt16 = stringFromHexString(str);
NSLog(@"bt16 ===%@",bt16);
return jpgImageSizeWithExactData(bt16);
}
}</span>
//2.PNG
<span style="color:#37bf36;">//由于图片的后缀不准确 所以用这个来判断类型
//- 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A
</span><span style="color:#cc0000;">NSData *pngData = stringFromHexString(@"89504e470d0a1a0a");</span><span style="color:#37bf36;">
//3.GIF
//- 文件头标识 (6 bytes) 47 49 46 38 39(37) 61
</span><span style="color:#cc0000;">NSData *gifData1 = stringFromHexString(@"474946383961");
NSData *gifData2 = stringFromHexString(@"474946383761");</span><span style="color:#37bf36;">
//4.JPEG/JPG
//- 文件头标识 (2 bytes): FF, D8 (SOI) (JPEG 文件标识)
</span><span style="color:#cc0000;">NSData *jpgData1 = stringFromHexString(@"ffd8");</span><span style="color:#37bf36;">
//- 文件结束标识 (2 bytes): FF, D9 (EOI)
</span><span style="color:#cc0000;">NSData *jpgData2 = stringFromHexString(@"ffd9");
NSData *verifitionPngData = [data subdataWithRange:NSMakeRange(0x00, 0x8)];
NSData *verifitionGifData = [data subdataWithRange:NSMakeRange(0x00, 0x6)];
NSData *verifitionJpgData = [data subdataWithRange:NSMakeRange(0x00, 0x2)];
if ([verifitionPngData isEqualToData:pngData]) {
self.type = PngImage;
}else if([verifitionGifData isEqualToData:gifData1] || [verifitionGifData isEqualToData:gifData2]) {
self.type = GifImage;
}else if([verifitionJpgData isEqualToData:jpgData1] || [verifitionJpgData isEqualToData:jpgData2]) {
self.type = JpgImage;
}else{
self.type = JpgImage;
}
</span>
补充:以上4种图片类型的特征码
1.BMP
-文件头标识 (2 bytes) 42 4D
2.PNG
- 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A
3.GIF
- 文件头标识 (6 bytes) 47 49 46 38 39(37) 61
4.JPEG/JPG
- 文件头标识 (2 bytes): FF, D8 (SOI) (JPEG 文件标识)
- 文件结束标识 (2 bytes): FF, D9 (EOI)