在聊天中加载图像,像 whatsapp 一样在本地保存得更快
Load Images in chat which is locally saved faster like whatsapp
我正在聊天 application.It 发送消息 text.Currently 我遇到一个问题,即从本地加载图像到 table 单元格的速度问题。
首先,我第一次将图像保存在文档目录中 download.Then 我正在检查它已经 existing.If 是的,然后我在后台线程上从本地获取该图像,这使得我的滚动速度很快但是当table 的双端队列方法正在工作,然后 imageview 得到白色背景,片刻之后图像反映在 imageview 中,这意味着从本地获取图像需要时间...... . . .
所以帮助我,我需要它和 whatsapp messanger 应用程序一样。
static NSString *simpleTableIdentifier = @"ZImageChatCell";
ZImageChatCell *cell = (ZImageChatCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ZImageChatCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
ChatMessageModel *messagemodel = [chatArray objectAtIndex:indexPath.row];
if([messagemodel.ismymessage boolValue])
{
NSData *imgdata = [Base64 decode:messagemodel.previewimage];
UIImage *effectImage = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageWithData:imgdata]];
[cell.rightimageview setImage:effectImage];
BOOL imageexist = [self checkImageExistsInLocal:messagemodel.message];
if(imageexist)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *tempimage = [self fetchImageFromLocal:messagemodel.message];
UIImage *newimage = [APPDELEGATE imageWithImage:tempimage scaledToFillSize:CGSizeMake(175, 175)];
dispatch_async(dispatch_get_main_queue(), ^{
cell.rightimageview.image = newimage;
});
});
}
else
{
if(messagemodel.message.length>0)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage * imggot = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:messagemodel.message]]];
UIImage *newimage = [APPDELEGATE imageWithImage:imggot scaledToFillSize:CGSizeMake(175, 175)];
[self saveImageLocally:imggot withUrlString:messagemodel.message];
dispatch_async(dispatch_get_main_queue(), ^{
cell.rightimageview.image = newimage;
[cell.rightactivityloader stopAnimating];
});
});
}
}
}
else
{
NSData *imgdata = [Base64 decode:messagemodel.previewimage];
UIImage *effectImage = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageWithData:imgdata]];
[cell.leftimageview setImage:effectImage];
BOOL imageexist = [self checkImageExistsInLocal:messagemodel.message];
if(imageexist)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *tempimage = [self fetchImageFromLocal:messagemodel.message];
UIImage *newimage = [APPDELEGATE imageWithImage:tempimage scaledToFillSize:CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH)];
dispatch_async(dispatch_get_main_queue(), ^{
cell.leftimageview.image = newimage;
});
});
}
else
{
if(messagemodel.message.length>0)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage * imggot = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:messagemodel.message]]];
UIImage *newimage = [APPDELEGATE imageWithImage:imggot scaledToFillSize:CGSizeMake(175, 175)];
[self saveImageLocally:imggot withUrlString:messagemodel.message];
dispatch_async(dispatch_get_main_queue(), ^{
cell.leftimageview.image = newimage;
[cell.leftactivityloader stopAnimating];
});
});
}
}
尝试创建用于从 url 下载图像的 UIImageView 类别文件,它会将文件保存在设备的缓存内存中,当您想要再次加载该图像时,它将从中加载该图像高速缓存。
UIImageView+Download.h
-(void)downloadFromURL:(NSString *)url withPlaceholder:(UIImage *)placehold;
UIImageView+Download.m
-(void)downloadFromURL:(NSString *)url withPlaceholder:(UIImage *)placehold
{
if (placehold) {
[self setImage:placehold];
}
if (url) {
//
if ([url rangeOfString:@"/Caches/"].location != NSNotFound) {
NSData *imageData=[NSData dataWithContentsOfFile:url];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
[self setImage:image];
[self setNeedsLayout];
}
return;
}
NSString *strImgName = [[[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] componentsSeparatedByString:@"/"] lastObject];
NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self applicationCacheDirectoryString],strImgName];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *aURL=[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([fileManager fileExistsAtPath:imagePath]==NO)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:aURL]];
[imageData writeToFile:imagePath atomically:YES];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:image];
[self setNeedsLayout];
});
}
});
}
else{
NSData *imageData=[NSData dataWithContentsOfFile:imagePath];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
[self setImage:image];
[self setNeedsLayout];
}
}
}
}
- (NSString *)applicationCacheDirectoryString
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return cacheDirectory;
}
在这里你只需要从你的class中调用这个方法就像
[cell.imageView downloadFromURL:YOUR_IMAGE_URL withPlaceholder:PLACEHOLDER_IMAGE];
这段代码对我有用
Swift 转换:-
func download(fromURL url: String, withPlaceholder placeholder: UIImage?) {
if placeholder != nil{
image = placeholder!
}
if url != "" {
if ((url as NSString).range(of: "/Caches/")).location != NSNotFound {
if let img = UIImage(contentsOfFile: url){
self.image = img
setNeedsLayout()
}
return
}
let str: String = (url as NSString).addingPercentEscapes(using: 4)!//NSUTF8StringEncoding
let strImg = str.components(separatedBy: "/").last!
let imagePath = "\(applicationCacheDirectoryString())/\(strImg)"
let fileManager = FileManager.default
let aURL = (url as NSString).addingPercentEscapes(using: 4)!
if fileManager.fileExists(atPath: imagePath) == false{
let queue = DispatchQueue.global(qos: .default)
queue.async(execute: {(_: Void) -> Void in
do{
let imageData = try Data(contentsOf: URL(string: aURL)!)
do{
let url = URL(fileURLWithPath: imagePath)
try imageData.write(to: url, options: .atomic)
if let img = UIImage(data: imageData){
DispatchQueue.main.async(execute: {() -> Void in
self.image = img
self.setNeedsLayout()
})
}
}catch{
print("Not able to save image in cache directory from url:\(aURL)")
}
}catch{
print("Not able to convert into Data from url:\(aURL)")
}
})
}else{
if let img = UIImage(contentsOfFile: imagePath){
self.image = img
setNeedsLayout()
}
}
}
}
func applicationCacheDirectoryString() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
let cacheDirectory: String? = (paths.count > 0) ? paths[0] : nil
return cacheDirectory ?? ""
}
我正在聊天 application.It 发送消息 text.Currently 我遇到一个问题,即从本地加载图像到 table 单元格的速度问题。
首先,我第一次将图像保存在文档目录中 download.Then 我正在检查它已经 existing.If 是的,然后我在后台线程上从本地获取该图像,这使得我的滚动速度很快但是当table 的双端队列方法正在工作,然后 imageview 得到白色背景,片刻之后图像反映在 imageview 中,这意味着从本地获取图像需要时间...... . . .
所以帮助我,我需要它和 whatsapp messanger 应用程序一样。
static NSString *simpleTableIdentifier = @"ZImageChatCell";
ZImageChatCell *cell = (ZImageChatCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ZImageChatCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
ChatMessageModel *messagemodel = [chatArray objectAtIndex:indexPath.row];
if([messagemodel.ismymessage boolValue])
{
NSData *imgdata = [Base64 decode:messagemodel.previewimage];
UIImage *effectImage = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageWithData:imgdata]];
[cell.rightimageview setImage:effectImage];
BOOL imageexist = [self checkImageExistsInLocal:messagemodel.message];
if(imageexist)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *tempimage = [self fetchImageFromLocal:messagemodel.message];
UIImage *newimage = [APPDELEGATE imageWithImage:tempimage scaledToFillSize:CGSizeMake(175, 175)];
dispatch_async(dispatch_get_main_queue(), ^{
cell.rightimageview.image = newimage;
});
});
}
else
{
if(messagemodel.message.length>0)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage * imggot = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:messagemodel.message]]];
UIImage *newimage = [APPDELEGATE imageWithImage:imggot scaledToFillSize:CGSizeMake(175, 175)];
[self saveImageLocally:imggot withUrlString:messagemodel.message];
dispatch_async(dispatch_get_main_queue(), ^{
cell.rightimageview.image = newimage;
[cell.rightactivityloader stopAnimating];
});
});
}
}
}
else
{
NSData *imgdata = [Base64 decode:messagemodel.previewimage];
UIImage *effectImage = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageWithData:imgdata]];
[cell.leftimageview setImage:effectImage];
BOOL imageexist = [self checkImageExistsInLocal:messagemodel.message];
if(imageexist)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *tempimage = [self fetchImageFromLocal:messagemodel.message];
UIImage *newimage = [APPDELEGATE imageWithImage:tempimage scaledToFillSize:CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH)];
dispatch_async(dispatch_get_main_queue(), ^{
cell.leftimageview.image = newimage;
});
});
}
else
{
if(messagemodel.message.length>0)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage * imggot = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:messagemodel.message]]];
UIImage *newimage = [APPDELEGATE imageWithImage:imggot scaledToFillSize:CGSizeMake(175, 175)];
[self saveImageLocally:imggot withUrlString:messagemodel.message];
dispatch_async(dispatch_get_main_queue(), ^{
cell.leftimageview.image = newimage;
[cell.leftactivityloader stopAnimating];
});
});
}
}
尝试创建用于从 url 下载图像的 UIImageView 类别文件,它会将文件保存在设备的缓存内存中,当您想要再次加载该图像时,它将从中加载该图像高速缓存。
UIImageView+Download.h
-(void)downloadFromURL:(NSString *)url withPlaceholder:(UIImage *)placehold;
UIImageView+Download.m
-(void)downloadFromURL:(NSString *)url withPlaceholder:(UIImage *)placehold
{
if (placehold) {
[self setImage:placehold];
}
if (url) {
//
if ([url rangeOfString:@"/Caches/"].location != NSNotFound) {
NSData *imageData=[NSData dataWithContentsOfFile:url];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
[self setImage:image];
[self setNeedsLayout];
}
return;
}
NSString *strImgName = [[[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] componentsSeparatedByString:@"/"] lastObject];
NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self applicationCacheDirectoryString],strImgName];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *aURL=[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([fileManager fileExistsAtPath:imagePath]==NO)
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:aURL]];
[imageData writeToFile:imagePath atomically:YES];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
[self setImage:image];
[self setNeedsLayout];
});
}
});
}
else{
NSData *imageData=[NSData dataWithContentsOfFile:imagePath];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
[self setImage:image];
[self setNeedsLayout];
}
}
}
}
- (NSString *)applicationCacheDirectoryString
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return cacheDirectory;
}
在这里你只需要从你的class中调用这个方法就像
[cell.imageView downloadFromURL:YOUR_IMAGE_URL withPlaceholder:PLACEHOLDER_IMAGE];
这段代码对我有用
Swift 转换:-
func download(fromURL url: String, withPlaceholder placeholder: UIImage?) {
if placeholder != nil{
image = placeholder!
}
if url != "" {
if ((url as NSString).range(of: "/Caches/")).location != NSNotFound {
if let img = UIImage(contentsOfFile: url){
self.image = img
setNeedsLayout()
}
return
}
let str: String = (url as NSString).addingPercentEscapes(using: 4)!//NSUTF8StringEncoding
let strImg = str.components(separatedBy: "/").last!
let imagePath = "\(applicationCacheDirectoryString())/\(strImg)"
let fileManager = FileManager.default
let aURL = (url as NSString).addingPercentEscapes(using: 4)!
if fileManager.fileExists(atPath: imagePath) == false{
let queue = DispatchQueue.global(qos: .default)
queue.async(execute: {(_: Void) -> Void in
do{
let imageData = try Data(contentsOf: URL(string: aURL)!)
do{
let url = URL(fileURLWithPath: imagePath)
try imageData.write(to: url, options: .atomic)
if let img = UIImage(data: imageData){
DispatchQueue.main.async(execute: {() -> Void in
self.image = img
self.setNeedsLayout()
})
}
}catch{
print("Not able to save image in cache directory from url:\(aURL)")
}
}catch{
print("Not able to convert into Data from url:\(aURL)")
}
})
}else{
if let img = UIImage(contentsOfFile: imagePath){
self.image = img
setNeedsLayout()
}
}
}
}
func applicationCacheDirectoryString() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
let cacheDirectory: String? = (paths.count > 0) ? paths[0] : nil
return cacheDirectory ?? ""
}