iOS根据图片URL获取图片的尺寸
场景:需要加载很多张高清的图片,列表显示
方案一:使用获取图像属性的方式来获取
1、写一个空的可变字典用来存高度值
根据 indexPath 生成 字符串 来用作key, 高度作为value,这为下面获取高度打下基础
2、从内存中查看有无缓存图片,有的话直接用图片的高度,没有的话先默认一个高度
3、循环获取图像属性获取高度
注意这里获取高度是耗时操作,使用 group 处理,待所有图片获取完高度即可刷新一下页面
具体实现,参考下面的代码
-(CGFloat)getimageHWithURLStr:(NSString*)imageStr withW:(CGFloat)imageW{ CGFloat itemBigImageH = WIN_WIDTH; if (imageStr == nil) { return itemBigImageH; } NSMutableString *imageURL = imageStr.mutableCopy; CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)[NSURL URLWithString:imageURL], NULL); if (source) { NSDictionary* imageHeader = (__bridge NSDictionary*) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL); if (imageHeader != NULL) { itemBigImageH = [[imageHeader objectForKey:@"PixelHeight"] floatValue]/[[imageHeader objectForKey:@"PixelWidth"] floatValue] * imageW; } // 必须释放 这个值一定不能为 NULL CFRelease(source); source = nil; } return itemBigImageH; }
for (int i = 0; i< _mTabData.count; i++) { NSArray *itemArr = V(_mTabData[i],@"item"); for (int j = 0; j <itemArr.count ; j++) { if ([V(itemArr[j],@"type") isEqualToString:@"images"]) { NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i]; NSString *str = [NSString stringWithFormat:@"%@_%@",@(indexPath.section),@(indexPath.row)]; // 默认高度 查看内存里是否有,有的就用内存的 NSLog(@"默认高度2-----%@---",str); UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:[NSString stringWithFormat:@"%@",V(itemArr[j],@"image")]]; if (image) { CGFloat iamgeWS = image.size.width / (WIN_WIDTH - 40); CGFloat iamgeHS = image.size.height / iamgeWS; [self.imageHeightArray setObject:[NSString stringWithFormat:@"%.2f",iamgeHS+6] forKey:str]; }else{ [self.imageHeightArray setObject:[NSString stringWithFormat:@"%.2f",WIN_WIDTH - 40+6] forKey:str]; } } } }
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_group_t group = dispatch_group_create(); for (int i = 0; i< _mTabData.count; i++) { NSArray *itemArr = V(_mTabData[i],@"item"); for (int j = 0; j <itemArr.count ; j++) { if ([V(itemArr[j],@"type") isEqualToString:@"images"]) { dispatch_group_enter(group); NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i]; NSString *str = [NSString stringWithFormat:@"%@_%@",@(indexPath.section),@(indexPath.row)]; dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 处理耗时操作的代码块... [self.imageHeightArray setObject:[NSString stringWithFormat:@"%.2f",[self getimageHWithURLStr:V(itemArr[j],@"image") withW:WIN_WIDTH - 40]+6] forKey:str]; //通知主线程刷新 dispatch_async(dispatch_get_main_queue(), ^{ // [self danhangShuaXinWith:indexPath]; // 主线程刷新i //回调或者说是通知主线程刷新, dispatch_group_leave(group); }); }); } } } dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"获取完所有图高度刷新------"); [_tableView reloadData]; }); }); });
方案二:使用SDWebImage里面的方法进行加载,然后拿到图片尺寸
1、同样的道理,首先也是要看缓存,有缓存用缓存
2、没有缓存直接使用sd加载,加载后使用通知的形式通知页面tableView的单行刷新
- (void)setUIWithImageStr:(NSString*)imagestr withIndexPath:(NSIndexPath*)indexPath{ WS _image = imagestr; if (imagestr == nil || [imagestr isEqualToString:@""]) { return; } UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:[NSString stringWithFormat:@"%@",imagestr]]; if (image) { CGFloat iamgeWS = image.size.width / (WIN_WIDTH); self.CellH = image.size.height / iamgeWS + 12.0; [self setupImageConstraninsWithImage:image]; }else{ weakSelf.CellH = WIN_WIDTH; [_vHeadPortraitImage setImageWithPureURLStr:imagestr completion:^(UIImage *image) { CGFloat iamgeWS = image.size.width / (WIN_WIDTH); weakSelf.CellH = image.size.height / iamgeWS + 12.0; [weakSelf setupImageConstraninsWithImage:image]; NSDictionary *dic = @{@"row":@(indexPath.row),@"section":@(indexPath.section),@"height":[NSString stringWithFormat:@"%.2f",(float)weakSelf.CellH]}; NSNotification *loadImageEnd = [[NSNotification alloc]initWithName:@"shuaXinImageCell" object:nil userInfo:dic]; [[NSNotificationCenter defaultCenter] postNotification:loadImageEnd]; }]; } }
- (void) shuaXinGoodsCell:(NSNotification *)notification { // 这里是加载后的通知 // NSLog(@"------notification---%@--",notification.userInfo); NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[notification.userInfo[@"row"] integerValue] inSection:[notification.userInfo[@"section"] integerValue]]; NSString *str = [NSString stringWithFormat:@"%@_%@",@(indexPath.section),@(indexPath.row)]; [self.imageHeightArray setObject:notification.userInfo[@"height"] forKey:str]; if (_mTabData.count != 0) { if (_mTabData.count > indexPath.section ) { NSArray *arr = V(_mTabData[indexPath.section],@"item"); if ([arr isKindOfClass:[NSArray class]]) { if (arr.count > indexPath.row) { [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } } } } }
方案对比:方案一可以在获取所有图片高度后就可以做一些操作,比如滚动到某一行,方案二则不能