最近练习做⼀一个微博的项⺫⽬目,看到新浪微博的图⽚片其实是可以根据图⽚片 的⼤大⼩小进⾏行预览区域⼤大⼩小的设置,如果固定区域⼤大⼩小有时候会导致图⽚片变形⽐比
较难看。google了很久,⼀一直没有找到答案,如果是图⽚片的⼤大⼩小单独对应⼀一组 数据然后放在微博的json数据中返回过来,那么也好解决,但是微博并没有提 供这样的接⼝口。后来我⼜又想是否有这样的请求命令可以直接索取图⽚片的⼤大⼩小, 那样的话我也可以不⽤用加载完图⽚片才能知道图⽚片的⼤大⼩小。可惜也没找到这样的 命令。
后来我觉得从最原始的⽅方式开始探索,我觉得图⽚片就是⽂文件,⽂文件就有⽂文 件头,⼀一般的⽂文件头⾥里⾯面都会有⽂文件的⼀一些常规信息,可能也包括图⽚片的⼤大⼩小。 所以,我在数据请求的时候,第⼀一次请求⽂文件头的数据或是更精确的话得到图 ⽚片⼤大⼩小所对应的字段的数据,那么整个包可能只需要很少的字节就能得到图⽚片 的⼤大⼩小,有了图⽚片得⼤大⼩小,我们就能设置预览区域的⼤大⼩小。 但是,还有⼀一个问题,图⽚片有很多种格式,所以⽂文件头肯定是不⼀一样的, 没办法这⾥里我是根据URL请求的后缀名进⾏行区分的。后续我测试了下,微博图 ⽚片主要就jpg和gif两种格式,然后我再加上常⽤用的png格式,这个demo中我就 是分析典型的三种图⽚片格式。 ⾸首先,对于这三种格式,⼤大家可以百度下,会有⽐比较详细的格式介绍,当 然很多内容我们并不需要,这⾥里我们只要知道图⽚片⼤大⼩小所在的据数段的位置即 可。
具体格式的信息我这边就不描述了,百度就很容易的查到。 当然jpg格式有点复杂,因为我在测试的时候,图⽚片⼤大⼩小所在的字段位置是 不固定的,所以会⿇麻烦些,具体⻅见Demo中的分析。 png的分析,png格式图⽚片⼤大⼩小的字段是在16-23,所以请求的时候只需要请求 8字节即可(是不是很⼩小)
!
{
NSString *URLString = @"http://img2.3lian.com/
img2007/13/29/20080409094710646.png";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:URLString]];
[request setValue:@"bytes=16-23" forHTTPHeaderField:@"Range"];
[[NSURLConnection connectionWithRequest:request delegate:self] start];
}
!
对应的每⼀一位都需要进⾏行转化,就能得到具体的数值
!
{
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);
}
格式⽐比较复杂所以先得了解清楚具体个字段的意思 因为图⽚片⼤大⼩小所在的字段区域不确定,所以我们要扩⼤大请求范围
这⾥里209字节⾥里⾯面应该就已经包含全了所有的数据(这⾥里我查了⼀一些资料,也 看了⼏几个不同jpg的⽂文件头16进制信息)
不⼀一定就完全正确,但是分析微博的jpg图⽚片⼤大⼩小暂时没有什么问题 复制代码
{
}
- (void)downloadJpgImage
NSString *URLString = @"http://ww3.sinaimg.cn/thumbnail/
673c0421jw1e9a6au7h5kj218g0rsn23.jpg";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:URLString]];
[request setValue:@"bytes=0-209" forHTTPHeaderField:@"Range"]; [[NSURLConnection connectionWithRequest:request delegate:self] start];
!
- (CGSize)jpgImageSizeWithHeaderData:(NSData *)data {
if ([data length] <= 0x58) { return CGSizeZero;
}
if ([data length] < 210) {// 肯定只有⼀一个DQT字段
short w1 = 0, w2 = 0;
[data getBytes:&w1 range:NSMakeRange(0x60, 0x1)];
[data getBytes:&w2 range:NSMakeRange(0x61, 0x1)];
short w = (w1 << 8) + w2;
short h1 = 0, h2 = 0;
[data getBytes:&h1 range:NSMakeRange(0x5e, 0x1)];
[data getBytes:&h2 range:NSMakeRange(0x5f, 0x1)];
short h = (h1 << 8) + h2;
return CGSizeMake(w, h);
} else {
short word = 0x0;
[data getBytes:&word range:NSMakeRange(0x15, 0x1)];
if (word == 0xdb) {
[data getBytes:&word range:NSMakeRange(0x5a, 0x1)]; if (word == 0xdb) {// 两个DQT字段
short w1 = 0, w2 = 0;
[data getBytes:&w1 range:NSMakeRange(0xa5, 0x1)];
[data getBytes:&w2 range:NSMakeRange(0xa6, 0x1)];
short w = (w1 << 8) + w2;
short h1 = 0, h2 = 0;
[data getBytes:&h1 range:NSMakeRange(0xa3, 0x1)];
[data getBytes:&h2 range:NSMakeRange(0xa4, 0x1)];
short h = (h1 << 8) + h2;
return CGSizeMake(w, h);
} else {// ⼀一个DQT字段
short w1 = 0, w2 = 0;
[data getBytes:&w1 range:NSMakeRange(0x60, 0x1)];
[data getBytes:&w2 range:NSMakeRange(0x61, 0x1)];
short w = (w1 << 8) + w2;
short h1 = 0, h2 = 0;
[data getBytes:&h1 range:NSMakeRange(0x5e, 0x1)];
[data getBytes:&h2 range:NSMakeRange(0x5f, 0x1)];
short h = (h1 << 8) + h2;
return CGSizeMake(w, h);
}
} else {
return CGSizeZero; }
}
} gif的分析和png差不多,不过这⾥里得到得应该是第⼀一张图⽚片的⼤大⼩小
- (void)downloadGifImage
{
NSString *URLString = @"http://img4.21tx.com/2009/1116/92/20392.gif";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:URLString]];
[request setValue:@"bytes=6-9" forHTTPHeaderField:@"Range"];
[[NSURLConnection connectionWithRequest:request delegate:self] start];
}
!
- (CGSize)gifImageSizeWithHeaderData:(NSData *)data
{
short w1 = 0, w2 = 0;
[data getBytes:&w1 range:NSMakeRange(0, 1)]; [data getBytes:&w2 range:NSMakeRange(1, 1)];
short w = w1 + (w2 << 8);
short h1 = 0, h2 = 0;
[data getBytes:&h1 range:NSMakeRange(2, 1)]; [data getBytes:&h2 range:NSMakeRange(3, 1)];
short h = h1 + (h2 << 8);
return CGSizeMake(w, h);
}
!