码迷,mamicode.com
首页 > 移动开发 > 详细

iOS下载图片之前获取网络图片尺寸的失败尝试

时间:2016-01-07 22:49:15      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:

最近一直在找获取网络图片的size的方式,最后得出两个结论:

1 使用分线程下载下来,然后获得图片的size

2 使用网络请求图片的头文件,然后从头文件中找到图片大小的信息

 

第一种方法需要主线程分线程切换,因为在使用tableView来reloadData的时候,刷表老是出问题,先放着不管

然后我重点是想搞一下第二个方法:

在网上找到了一个博客:http://cxjwin.github.io/2013/11/05/preview_image_size/

大神写的很不错

主要思路就是先在网上找一个图片头文件的格式,然后对照着请求回来的data数据来进行查找,找到图片宽高的地方,解析出来

以png格式为例,先放一段代码:

        case PngImage:
        {
            NSString *URLString = @"http://pic12.nipic.com/20110118/1295091_171039317000_2.png";
            NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.0f];
            NSString *range=[NSString stringWithFormat:@"Bytes=16-23"];
            [request setValue:range forHTTPHeaderField:@"Range"];
            NSURLResponse *response=nil;
            NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
            
            CGSize size = pngImageSizeWithHeaderData(data);
            NSLog(@"png image size : %@", NSStringFromCGSize(size));
        }

 或者这样的

    NSString *URLString = @"http://pic12.nipic.com/20110118/1295091_171039317000_2.png";
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URLString]];
    [request setValue:kPngRangeValue forHTTPHeaderField:@"Range"];
    [[NSURLConnection connectionWithRequest:request delegate:self] start];

 请求方式不同,原理是一样的

然后就是对获取到的data进行解析

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);
}

 在我的试验中,获取到的data数值为<00000400 000002ad>,只有八字节,前四位是width,后四位是height

这是他看过png的格式,所以在获取数据的时候只需要16-23位

data数据是以16进制数展示的,其实应该是 <00 00 04 00 00 00 02 ad>,每两个数代表8位,二进制中8位一个字节,这里换算一下,四个数可以表示一个字节

这个清楚了之后就可以照着网上的头文件解析来解析这些16进制数

下面放上网上的对jpeg头文件的部分解析

技术分享

技术分享

技术分享

技术分享

这些都还正常,放一段我获取到的data的分析记录

ff d8(soi) ff e0(appo)      00 10(数据长度) 4a 46    49 46 00(标示符) 01   02(版本号) 01(密度单位) 00 48(x密度) 00 48 (y密度)00(缩略图水平像素数目)00(缩略图垂直像素数目) ffed002c 50686f74

然后后面就奇葩起来了

技术分享

 

然后我发现了我截取的data数据里各种appn标记码,然后这玩意儿是不知道有多长,有多少的,然后那个存着图片尺寸的标记码

技术分享

ffc0被埋在data的汪洋大海里,我使用搜索找到了它,但是已经毛用没有了

技术分享

 

瞬间,心都碎了

能获取png,gif格式的图片大小,因为png和gif格式的图片头文件固定,可以准确找到宽高所在字节,只需要极少流量就可以获得图片大小
但是jpeg的头文件很混乱,我真的想说它根本就不分header和body,绘图软件编辑一次保存一次就添加一个标记码,然后存放宽高的标记码就消失在数据流的某个地方了,因为不知道有多少个绘图软件编辑过,也不知道绘图软件标记码里面的内容格式,所以手动获取jpeg图片的宽高基本不可能了

我这么多天都白玩儿了

还是去捣鼓一下分线程吧,要不去搞一下webView,都比这个靠谱啊,,,

jpeg怎么可以这么坑

 

iOS下载图片之前获取网络图片尺寸的失败尝试

标签:

原文地址:http://www.cnblogs.com/chebaodaren/p/5111423.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!