首页 > 代码库 > 不同格式图片的高效获取

不同格式图片的高效获取

   最近练习做?一个微博的项??目,看到新浪微博的图?片其实是可以根据图?片的?大?小进?行预览区域?大?小的设置,如果固定区域?大?小有时候会导致图?片变形?比

较难看。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);

}