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];
                }
            }
        }
    }
}

方案对比:方案一可以在获取所有图片高度后就可以做一些操作,比如滚动到某一行,方案二则不能

原文地址:https://www.cnblogs.com/ljcgood66/p/13819183.html