比较原始的方法:
AsyncImageView.h:
#import <UIKit/UIKit.h>
@interface AsyncImageView : UIView
{
NSURLConnection* connection;
NSMutableData* data;
}
– (void)loadImageFromURL:(NSURL*)url;
@end
AsyncImageView.m:
#import “AsyncImageView.h”
@implementation AsyncImageView
– (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self) {
// Initialization code
}
returnself;
}
– (void)loadImageFromURL:(NSURL*)url {
if(connection!=nil) { [connection release]; }
if(data!=nil) { [data release]; }
NSURLRequest* request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
– (void)connection:(NSURLConnection *)theConnection
didReceiveData:(NSData *)incrementalData {
if(data==nil) {
data =
[[NSMutableData alloc] initWithCapacity:2048];
}
[data appendData:incrementalData];
}
– (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
[connection release];
connection=nil;
if([[self subviews] count] > 0) {
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight );
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout];
[self setNeedsLayout];
[data release];
data=nil;
}
– (UIImage*) image {
UIImageView* iv = [[self subviews] objectAtIndex:0];
return[iv image];
}
– (void)dealloc {
[connection cancel];
[connection release];
[data release];
[super dealloc];
}
@end
#import <UIKit/UIKit.h>
@interface AsyncImageView : UIView
{
NSURLConnection* connection;
NSMutableData* data;
}
– (void)loadImageFromURL:(NSURL*)url;
@end
AsyncImageView.m:
#import “AsyncImageView.h”
@implementation AsyncImageView
– (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self) {
// Initialization code
}
returnself;
}
– (void)loadImageFromURL:(NSURL*)url {
if(connection!=nil) { [connection release]; }
if(data!=nil) { [data release]; }
NSURLRequest* request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
– (void)connection:(NSURLConnection *)theConnection
didReceiveData:(NSData *)incrementalData {
if(data==nil) {
data =
[[NSMutableData alloc] initWithCapacity:2048];
}
[data appendData:incrementalData];
}
– (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
[connection release];
connection=nil;
if([[self subviews] count] > 0) {
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight );
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout];
[self setNeedsLayout];
[data release];
data=nil;
}
– (UIImage*) image {
UIImageView* iv = [[self subviews] objectAtIndex:0];
return[iv image];
}
– (void)dealloc {
[connection cancel];
[connection release];
[data release];
[super dealloc];
}
@end
方法二:
@interface UIButton (AsyncImage)
//size by point
– (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage;
@end
@implementation UIButton (AsyncImage)
– (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
image = [UIImage imageWithData:data];
if (image) {
if (!CGSizeEqualToSize(size, CGSizeZero)) {
image = [UIImage imageWithCGImage:image.CGImage scale:[self scaleImage:image adjustToSize:size] orientation:image.imageOrientation];
}
if (logoImage) {
image = [self addLogoImage:logoImage toImage:image];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:image forState:UIControlStateNormal];
completion();
});
}
else {
NSLog(@”async load error.”);
}
});
}
// 缩放图片以适应按钮大小
– (CGFloat)scaleImage:(UIImage *)image adjustToSize:(CGSize)size
{
CGFloat xScale = size.width / image.size.width;
CGFloat yScale = size.height / image.size.height;
return 1.0 / MIN(xScale, yScale);
}
– (UIImage *)addLogoImage:(UIImage *)logo toImage:(UIImage *)img
{
//get image width and height
CGFloat scale = [UIScreen mainScreen].scale;
int w = scale * img.size.width;
int h = scale * img.size.height;
int logoWidth = logo.scale * logo.size.width;
int logoHeight = logo.scale * logo.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//create a graphic context with CGBitmapContextCreate
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextDrawImage(context, CGRectMake(w – logoWidth, 0, logoWidth, logoHeight), [logo CGImage]);
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked scale:scale orientation:img.imageOrientation];
}
@end
//size by point
– (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage;
@end
@implementation UIButton (AsyncImage)
– (void)setImageFromURL:(NSString *)urlString adjustToSize:(CGSize)size completion:(void (^)(void))completion logo:(UIImage *)logoImage
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
image = [UIImage imageWithData:data];
if (image) {
if (!CGSizeEqualToSize(size, CGSizeZero)) {
image = [UIImage imageWithCGImage:image.CGImage scale:[self scaleImage:image adjustToSize:size] orientation:image.imageOrientation];
}
if (logoImage) {
image = [self addLogoImage:logoImage toImage:image];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:image forState:UIControlStateNormal];
completion();
});
}
else {
NSLog(@”async load error.”);
}
});
}
// 缩放图片以适应按钮大小
– (CGFloat)scaleImage:(UIImage *)image adjustToSize:(CGSize)size
{
CGFloat xScale = size.width / image.size.width;
CGFloat yScale = size.height / image.size.height;
return 1.0 / MIN(xScale, yScale);
}
– (UIImage *)addLogoImage:(UIImage *)logo toImage:(UIImage *)img
{
//get image width and height
CGFloat scale = [UIScreen mainScreen].scale;
int w = scale * img.size.width;
int h = scale * img.size.height;
int logoWidth = logo.scale * logo.size.width;
int logoHeight = logo.scale * logo.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//create a graphic context with CGBitmapContextCreate
CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
CGContextDrawImage(context, CGRectMake(w – logoWidth, 0, logoWidth, logoHeight), [logo CGImage]);
CGImageRef imageMasked = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return [UIImage imageWithCGImage:imageMasked scale:scale orientation:img.imageOrientation];
}
@end
方法三:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# import <Foundation/Foundation.h> # import "StringUtils.h" @interface ImageManager : NSObject { NSMutableDictionary *_imageDict; NSMutableArray *_imageArr; } @property (nonatomic, strong) NSString *httpUrl; @property (nonatomic, strong) NSMutableDictionary *imageDict; @property (nonatomic, assign) dispatch_queue_t networkQueue; + (ImageManager *) sharedInstance; - ( void )asyncImage:(NSString *)imageName imageView:(UIImageView *)imageView; //插队 - ( void )asyncImageInsert:(NSString *)imageName imageView:(UIImageView *)imageView insert:(BOOL)insert; //不要在下载之前的数据 - ( void )asyncImageCleanOld:(NSString *)imageName imageView:(UIImageView *)imageView cleanOld:(BOOL)cleanOld; @end |
实现文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
// // ImageManager.m // myb-ios // // Created by warrior gao on 13-6-5. // Copyright (c) 2013年 51myb. All rights reserved. // # import "ImageManager.h" @interface ImageManager() @end @implementation ImageManager //缓存图片的最大数量 static int counter = 0 ; @synthesize imageDict = _imageDict; //Singleton + (ImageManager *)sharedInstance { static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = self. new ; }); return instance; } - (id)init { if ((self = [ super init])) { self.networkQueue = dispatch_queue_create( "com.warrior.network.image" , nil); _imageDict = [[NSMutableDictionary alloc] init]; _imageArr = [[NSMutableArray alloc] init]; } return self; } - (NSString *) fileFullPath:(NSString *)fileName { NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex: 0 ]; NSString *fileFullPath = [NSString stringWithFormat:@ "%@/%@" ,cachePath,fileName]; return fileFullPath; } //不要在下载之前的数据 - ( void )asyncImageCleanOld:(NSString *)imageName imageView:(UIImageView *)imageView cleanOld:(BOOL)cleanOld { if (cleanOld) { [_imageArr removeAllObjects]; } [self asyncImage:imageName imageView:imageView]; } //插队,优先 - ( void )asyncImageInsert:(NSString *)imageName imageView:(UIImageView *)imageView insert:(BOOL)insert { if ([StringUtils isEmpty:imageName]){ return ; } NSData *data = [NSData dataWithContentsOfFile:[self fileFullPath:[imageName stringByReplacingOccurrencesOfString:@ "/" withString:@ "-" ]]]; if (data == nil){ [_imageDict setValue:imageView forKey:imageName]; if (insert) { [_imageArr insertObject:imageName atIndex: 0 ]; } else { [_imageArr addObject:imageName]; } [self cacheImage]; } else { [imageView setImage:[UIImage imageWithData:data]]; } } //正常,附加到后面 - ( void )asyncImage:(NSString *)imageName imageView:(UIImageView *)imageView { [self asyncImageInsert:imageName imageView:imageView insert:NO]; } //异步缓存图片到本地,最多有两个线程 -( void )cacheImage { for (; counter < 2 && _imageArr.count > 0 ; counter++) { NSString *imageName = nil; @synchronized (self){ imageName = [[_imageArr objectAtIndex: 0 ] copy]; [_imageArr removeObjectAtIndex: 0 ]; } if (imageName == nil) continue ; dispatch_async(self.networkQueue, ^{ NSLog(@ "Starting: %@" , imageName); UIImage *avatarImage = nil; NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@ "%@%@" ,self.httpUrl, imageName]]; NSData *responseData = [NSData dataWithContentsOfURL:url]; if (responseData.length > 0 ) { [responseData writeToFile:[self fileFullPath:[imageName stringByReplacingOccurrencesOfString:@ "/" withString:@ "-" ]] atomically:NO]; avatarImage = [UIImage imageWithData:responseData]; NSLog(@ "Finishing: %@" , imageName); if (avatarImage) { dispatch_async(dispatch_get_main_queue(), ^{ UIImageView *imageView = [_imageDict objectForKey:imageName]; if (imageView != nil && avatarImage != nil){ [imageView setImage:avatarImage]; } [_imageDict removeObjectForKey:imageName]; [imageName release]; }); } } counter--; [self cacheImage]; }); } } @end |
© 版权声明
本文刊载的所有内容,包括文字、图片、音频、视频、软件、程序、以及网页版式设计等部门来源于互联网,版权均归原作者所有!本网站提供的内容服务于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。
联系信息:邮箱aoxolcom@163.com或见网站底部。
联系信息:邮箱aoxolcom@163.com或见网站底部。
THE END
请登录后发表评论
注册
社交帐号登录