iOS开发中用imageIO渐进加载图片及获取exif的方法
imageIO完成渐进加载图片
一、常见渐进加载图片模式
目前我们看到的渐进加载主要有以下三种实现方式:
1) 依次从web上加载不同尺寸的图片,从小到大。最开始先拉取一个小缩略图做拉伸显示,然后拉取中等规格的图,拉取完毕直接覆盖显示,最后拉取原图,拉取完成后显示原图。
2)直接从web上拉取最大的图片,每接受一点儿数据就显示一点儿图片,这样就会实现从上到下一点点刷新出来的效果。
3)结合第1种和第2种,先拉取一个缩略图做拉伸显示,然后采用第二种方法直接拉取原图,这样即可以实现渐进加载,也可以节省几次中间的网络请求。
二、通过imageIO实现图片的渐进加载
imageIO的guide中原话是这么说的:"Ifyouhaveaverylargeimage,orareloadingimagedataovertheweb,youmaywanttocreateanincrementalimagesourcesothatyoucandrawtheimagedataasyouaccumulateit."
翻译过来就是:"如果你想加载一副特别大的图片,或者从网络上加载一副图片,你可以通过创建一个imageSource实现渐进加载的效果。"翻译的不是很地道,大概就是这么个意思,以前在做PowerCam的时候,当时为了在iOS上处理超大图的时候也试过这种方法,当时测试使用的是一副中国地图,分辨率为10000*8000的,结果是当整幅图片加载到内存时,内存吃不消,于是就放弃了。现在想想对于这种超大图片的处理,我们可以采用分片的方式进行,每次只需要处理一小块图片即可,这个问题就留给大家思考吧。
今天我们要讨论的是CGImageSource实现从web端渐进加载图片,要达到这个目的我们需要创建一个URLConnnection,然后实现代理,每次接收到数据时更新图片即可。下面主要的实现源码:
// // SvIncrementallyImage.m // SvIncrementallyImage // // Createdby mapleon6/27/13. // Copyright(c)2013maple.Allrightsreserved. //
#import"SvIncrementallyImage.h" #import<ImageIO/ImageIO.h> #import<CoreFoundation/CoreFoundation.h>
@interfaceSvIncrementallyImage(){ NSURLRequest *_request; NSURLConnection*_conn; CGImageSourceRef_incrementallyImgSource; NSMutableData *_recieveData; longlong _expectedLeght; bool _isLoadFinished; }
@property(nonatomic,retain)UIImage*image; @property(nonatomic,retain)UIImage*thumbImage;
@end
@implementationSvIncrementallyImage
@synthesizeimageURL=_imageURL; @synthesizeimage =_image; @synthesizethumbImage=_thumbImage;
-(id)initWithURL:(NSURL*)imageURL { self=[superinit]; if(self){ _imageURL=[imageURLretain]; _request=[[NSURLRequestalloc]initWithURL:_imageURL]; _conn =[[NSURLConnectionalloc]initWithRequest:_requestdelegate:self]; _incrementallyImgSource=CGImageSourceCreateIncremental(NULL); _recieveData=[[NSMutableDataalloc]init]; _isLoadFinished=false; } returnself; }
#pragmamark- #pragmamarkNSURLConnectionDataDelegate
-(void)connection:(NSURLConnection*)connectiondidReceiveResponse:(NSURLResponse*)response { _expectedLeght=response.expectedContentLength; NSLog(@"expectedLength:%lld",_expectedLeght); NSString*mimeType=response.MIMEType; NSLog(@"MIMETYPE%@",mimeType); NSArray*arr=[mimeTypecomponentsSeparatedByString:@"/"]; if(arr.count<1||![[arrobjectAtIndex:0]isEqual:@"image"]){ NSLog(@"notaimageurl"); [connectioncancel]; [_connrelease];_conn=nil; } }
-(void)connection:(NSURLConnection*)connectiondidFailWithError:(NSError*)error { NSLog(@"Connection%@error,errorinfo:%@",connection,error); }
-(void)connectionDidFinishLoading:(NSURLConnection*)connection { NSLog(@"ConnectionLoadingFinished!!!"); //ifdownloadimagedatanotcomplete,createfinalimage if(!_isLoadFinished){ CGImageSourceUpdateData(_incrementallyImgSource,(CFDataRef)_recieveData,_isLoadFinished); CGImageRefimageRef=CGImageSourceCreateImageAtIndex(_incrementallyImgSource,0,NULL); self.image=[UIImageimageWithCGImage:imageRef]; CGImageRelease(imageRef); } }
-(void)connection:(NSURLConnection*)connectiondidReceiveData:(NSData*)data { [_recieveDataappendData:data]; _isLoadFinished=false; if(_expectedLeght==_recieveData.length){ _isLoadFinished=true; } CGImageSourceUpdateData(_incrementallyImgSource,(CFDataRef)_recieveData,_isLoadFinished); CGImageRefimageRef=CGImageSourceCreateImageAtIndex(_incrementallyImgSource,0,NULL); self.image=[UIImageimageWithCGImage:imageRef]; CGImageRelease(imageRef); }
@end