在iOS开发过程中经常需要通过网络请求加载图片,有时,需要在创建UIImageView或UIButton来显示图片之前需要提前知道图片的尺寸,根据图片尺寸创建对应大小的控件。但是对于网络图片来说,要想通过最优的方法获得尺寸就略微有点困难,大体思路就是下面这种:

如果有使用SDWebImage,则首先检查是否缓存过该图片,如果没有,先通过文件头获取图片大小(针对格式为png、gif、jpg文件获取其尺寸大小),如果获取失败,则下载完整的图片data,然后计算大小,如果有使用SDWebImage,则使用SDWebImage缓存该图片。

+(CGSize)downloadImageSizeWithURL:(id)imageURL

{

NSURL* URL = nil;

if([imageURL isKindOfClass:[NSURL class]]){

URL = imageURL;

}

if([imageURL isKindOfClass:[NSString class]]){

URL = [NSURL URLWithString:imageURL];

}

if(URL == nil)

return CGSizeZero;

#ifdef dispatch_main_sync_safe

if([[SDImageCache sharedImageCache] diskImageExistsWithKey:absoluteString])

{

UIImage* image = [[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:absoluteString];

if(!image)

{

NSData* data = [[SDImageCache sharedImageCache] performSelector:@selector(diskImageDataBySearchingAllPathsForKey:) withObject:URL.absoluteString];

image = [UIImage imageWithData:data];

}

if(image)

{

return image.size;

}

}

#endif

NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:URL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1];

NSString* pathExtendsion = [URL.pathExtension lowercaseString];

CGSize size = CGSizeZero;

if ([pathExtendsion rangeOfString:@"png"].location != NSNotFound) {

size =  [self downloadPNGImageSizeWithRequest:request];

}

else if([pathExtendsion rangeOfString:@"gif"].location != NSNotFound)

{

size =  [self downloadGIFImageSizeWithRequest:request];

}

else{

size = [self downloadJPGImageSizeWithRequest:request];

}

if(CGSizeEqualToSize(CGSizeZero, size))

{

NSData* data = [NSData dataWithContentsOfURL:URL];

UIImage* image = [UIImage imageWithData:data];

if(image)

{

//如果未使用SDWebImage,则忽略;缓存该图片

#ifdef dispatch_main_sync_safe

[[SDImageCache sharedImageCache] storeImage:image recalculateFromImage:YES imageData:data forKey:URL.absoluteString toDisk:YES];

#endif

size = image.size;

}

}

//过滤掉不符合大小的图片,大图太大浪费流量,用户体验不好

if (size.height > 2048 || size.height <= 0 || size.width > 2048 || size.width <= 0 ) {

return CGSizeZero;

}

else

{

return size;

}

}

+(CGSize)downloadPNGImageSizeWithRequest:(NSMutableURLRequest*)request

{

[request setValue:@"bytes=16-23" forHTTPHeaderField:@"Range"];

NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

if(data.length == 8)

{

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

}

return CGSizeZero;

}

+(CGSize)downloadGIFImageSizeWithRequest:(NSMutableURLRequest*)request

{

[request setValue:@"bytes=6-9" forHTTPHeaderField:@"Range"];

NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

if(data.length == 4)

{

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

}

return CGSizeZero;

}

+(CGSize)downloadJPGImageSizeWithRequest:(NSMutableURLRequest*)request

{

[request setValue:@"bytes=0-209" forHTTPHeaderField:@"Range"];

NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

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;

}

}

}

iOS获取网络图片大小的更多相关文章

  1. [转载] IOS 获取网络图片的大小 改变 图片色值 灰度什么的方法集合

    IOS 获取网络图片的大小 改变 图片色值 灰度什么的方法集合

  2. iOS 获取网络图片的大小

    一直都在找关于获取网络图片的大小的方法, 今天找到了一个能解决的办法 ,如下 1, 导入框架 #import <ImageIO/ImageIO.h> 2. 使用此方法得到image的siz ...

  3. iOS 获取内存大小使用情况(进度条显示)

    一.获取设备内存大小方法 //返回存储内存占用比例 - (NSString *)getFreeDiskspaceRate{ float totalSpace; .f; NSError *error = ...

  4. java 获取图片大小(尺寸)

    1,获取本地图片大小(尺寸) File picture=new File(strSrc);BufferedImage sourceImg=ImageIO.read(new FileInputStrea ...

  5. IOS -- 获取本地图片和网络图片的大小size

    // 获取图片的size CGSize size = [UIImage imageNamed:@"regStep2_sex"].size; 获取网络图片的尺寸: // 根据图片ur ...

  6. 分享一个安卓中异步获取网络图片并自适应大小的第三方程序(来自github)

    安卓中获取网络图片,生成缓存 用安卓手机,因为手机流量的限制,所以我们在做应用时,要尽量为用户考虑,尽量少耗点用户的流量,而在应用中网络图片的显示无疑是消耗流量最大的,所以我们可以采取压缩图片或者将图 ...

  7. 获取网络图片的大小 改变 图片色值 灰度什么的方法集合-b

    直接上代码了 头文件 // 图片处理 0 半灰色  1 灰度   2 深棕色    3 反色 +(UIImage*)imageWithImage:(UIImage*)image grayLevelTy ...

  8. IOS 获取网络图像尺寸 更改 图像色彩值 什么一套方法灰色

    直接在代码 头文件 // 图片处理 0 半灰色 1 灰度 2 深棕色 3 反色 +(UIImage*)imageWithImage:(UIImage*)image grayLevelType:(UII ...

  9. cocos2d-x C++ 获取网络图片缓存并展示

    #ifndef __HttpGetImg__ #define __HttpGetImg__ #include "cocos2d.h" #include "HttpRequ ...

随机推荐

  1. 机器指令翻译成 JavaScript —— 终极目标

    上一篇,我们顺利将 6502 指令翻译成 C 代码,并演示了一个案例. 现在,我们来完成最后的目标 -- 转换成 JavaScript. 中间码输出 我们之所以选择 C,就是为了使用 LLVM.现在来 ...

  2. Xamarin.Android活动的生命周期

    一.前言 用过Android手机的人一定会发现一种现象,当你把一个应用置于后台后,一段时间之后在打开就会发现应用重新打开了,但是之前的相关的数据却没有丢失.可以看出app的“生命”是掌握在系统手上的, ...

  3. 使用Hystrix提高系统可用性

    今天稍微复杂点的互联网应用,服务端基本都是分布式的,大量的服务支撑起整个系统,服务之间也难免有大量的依赖关系,依赖都是通过网络连接起来. (图片来源:https://github.com/Netfli ...

  4. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

  5. DAO层,Service层,Controller层、View层 的分工合作

    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口 ...

  6. Android开发学习之路-机器学习库(图像识别)、百度翻译

    对于机器学习也不是了解的很深入,今天无意中在GitHub看到一个star的比较多的库,就用着试一试,效果也还行.比是可能比不上TensorFlow的,但是在Android上用起来比较简单,毕竟Tens ...

  7. .NET Core下的日志(1):记录日志信息

    记录各种级别的日志是所有应用不可或缺的功能.关于日志记录的实现,我们有太多第三方框架可供选择,比如Log4Net.NLog.Loggr和Serilog 等,当然我们还可以选择微软原生的诊断机制(相关A ...

  8. JVM学习(3)——总结Java内存模型

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...

  9. 学习Spring——两个你熟悉的不能再熟悉的场景使用

    最近公众号受邀获取了留言和赠送模板的权限,小开心(欢迎去公众号JackieZheng围观). 我们大致的了解了Spring这个框架对于依赖注入的使用和诠释可谓是淋漓尽致.因为有了Spring的这个IO ...

  10. ASP.NET Core 中文文档 第三章 原理(12)托管

    原文:Hosting 作者:Steve Smith 翻译:娄宇(Lyrics) 校对:何镇汐.许登洋(Seay) 为了运行 ASP.NET Core 应用程序,你需要使用 WebHostBuilder ...