无法将本地存储的图像更快地加载到集合视图中。?
Posted
技术标签:
【中文标题】无法将本地存储的图像更快地加载到集合视图中。?【英文标题】:Unable to load locally stored images faster into collection view.? 【发布时间】:2016-03-28 12:11:07 【问题描述】:我有多个图像和视频存储在应用程序文档目录中。我以这种方式使用 SDWebImage 在集合视图中显示图像和视频。
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
AlbumImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AlbumImageCell" forIndexPath:indexPath];
cell.albumImage.image=nil;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
if (cell == nil)
cell = [[[NSBundle mainBundle] loadNibNamed:@"AlbumImageCell" owner:self options:nil] objectAtIndex:0];
NSInteger Type=[[[self.arrTbl_Album_Image objectAtIndex:indexPath.row] objectAtIndex:3] intValue];
if (Type==1)
cell.imgPlay.hidden=YES;
[cell.albumImage setImage:[images objectAtIndex:indexPath.row]];
else
cell.imgPlay.hidden=NO;
[cell.albumImage setImage:[images objectAtIndex:indexPath.row]];
return cell;
这里是生成缩略图的代码。
-(void)load_Album_Data
NSUserDefaults *album_id=[NSUserDefaults standardUserDefaults];
NSInteger Album_id=[album_id integerForKey:@"album_Id"];
//From the query.
NSString *query=[NSString stringWithFormat:@"select * from tbl_Album_Image where album_id='%ld' order by id desc",Album_id];
//Get result.
if (self.arrTbl_Album_Image != nil)
self.arrTbl_Album_Image=nil;
self.arrTbl_Album_Image=[[NSArray alloc]initWithArray:[self.dbManager loadDataFromDB:query]];
dispatch_queue_t myQueue = dispatch_queue_create("MyQueue",NULL);
dispatch_async(myQueue, ^
for(int i=0;i<self.arrTbl_Album_Image.count;i++)
NSInteger AssetType=[[[self.arrTbl_Album_Image objectAtIndex:i] objectAtIndex:3] intValue];
if (AssetType==1)
//for image
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *inputPath = [[self.arrTbl_Album_Image objectAtIndex:i]objectAtIndex:2 ];
NSString *imageEx=[inputPath pathExtension];
NSString *imageName=[[inputPath lastPathComponent]stringByDeletingPathExtension];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@",imageName,imageEx]];
UIImage *img=[UIImage imageWithContentsOfFile:fullPath];
CGFloat scale = MAX(106/img.size.width, 106/img.size.height);
CGFloat width = img.size.width * scale;
CGFloat height = img.size.height * scale;
CGRect imageRect = CGRectMake((106 - width)/2.0f,
(106 - height)/2.0f,
width,
height);
CGSize c=CGSizeMake(106, 106);
UIGraphicsBeginImageContextWithOptions(c, NO, 0);
[img drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[images addObject:newImage];
else
//for video
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *inputPath = [[self.arrTbl_Album_Image objectAtIndex:i]objectAtIndex:2 ];
NSString *imageEx=[inputPath pathExtension];
NSString *imageName=[[inputPath lastPathComponent]stringByDeletingPathExtension];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@",imageName,imageEx]];
NSURL *videoURL = [NSURL fileURLWithPath:fullPath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
imageGenerator.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *thumbNailImage = [[UIImage alloc] initWithCGImage:imageRef];
CGFloat scale = MAX(106/thumbNailImage.size.width, 106/thumbNailImage.size.height);
CGFloat width = thumbNailImage.size.width * scale;
CGFloat height = thumbNailImage.size.height * scale;
CGRect imageRect = CGRectMake((106 - width)/2.0f,
(106 - height)/2.0f,
width,
height);
CGSize c=CGSizeMake(106, 106);
UIGraphicsBeginImageContextWithOptions(c, NO, 0);
[thumbNailImage drawInRect:imageRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[images addObject:newImage];
dispatch_async(dispatch_get_main_queue(), ^
//Reload the Image view.
[self.album_ImageView reloadData];
);
);
但问题是我无法更快地加载图像,并且当快速上下滚动时应用程序崩溃。并且对于未生成的视频图像也是如此。 请帮我解决这个问题并为我提供任何解决方案。 我希望在集合视图单元格中快速加载图像。
【问题讨论】:
给出崩溃、消息和堆栈跟踪的详细信息 @Wain 查看详情 1) 收到内存警告。2) 通信错误:而不是你的代码来设置图像更改
[cell.albumImage sd_setImageWithURL:imaURL placeholderImage:[UIImage imageNamed:@"placeholder.png"] options:SDWebImageRefreshCached completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
dispatch_async(dispatch_get_main_queue(), ^
cell.albumImage.image=image;
);
];
加载速度更快,甚至可以保存在缓存中
【讨论】:
收到内存警告并且应用程序崩溃。 查看此详细信息 1) 收到内存警告。2) 通信错误:似乎当您从照片库中保存图像时,如果需要,您应该保存完整尺寸,并保存可用于在应用中显示的图像的适当缩放版本。如果使用ALAsset
,那很可能是thumbnail
。
如果你这样做,图像加载会很快并且内存使用量最小。
目前,您只是试图将过多的图像数据加载到内存中,这会花费很长时间,并且当应用程序不可避免地用完时会导致应用程序崩溃。使用设备相机拍摄的图像实际上非常大......
【讨论】:
是的,我应用这种方法并创建缩略图以在单元格中显示。而且对我来说也很好,但是在生成图像缩略图的时候仍然有负载。看到我正在编辑我的代码。告诉我这是不是正确的方法。因为每次我进入特定专辑时都会加载图像。 如果您将主图像保存到磁盘,我也会将缩略图保存在主图像旁边的目录中并具有相同的名称,这样您就不需要一直这样做.以上是关于无法将本地存储的图像更快地加载到集合视图中。?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法将图像从本地存储加载到 Flutter 中 CircleAvatar 小部件的 backgroundImage 属性?